---
status: accepted
---

# Milestones are parent issues with sub-issues, not native GitHub milestones

Every buildable Request must map to a Milestone, and Milestones are cheap and frequent (one may hold a single Request). We represent a Milestone as an ordinary issue tagged `kind: MILESTONE`, with its member Requests attached as native GitHub **sub-issues**, rather than as a native GitHub milestone. Greenlighting a Request adds it as a sub-issue of its Milestone (`gh issue edit --add-sub-issue`); a release's `fixes #<milestone-issue>` closes the parent alongside the `fixes #N` that close its children.

## Considered Options

- **Native GitHub milestones** — give a progress bar and due dates in the web UI, but are per-repo, carry only title/description/due, and would be a second construct alongside the issue model. Managing them means `gh api` (no porcelain), and they don't tie to releases natively.
- **Plain cross-references** (the first sketch: a milestone issue that merely references its members) — works, but forfeits the native rollup that sub-issues give.

## Consequences

Everything is an issue: one CRUD path, and a Milestone carries a body, comments, its own State, and a `subIssuesSummary` completion rollup ("5 of 8 done") for free. Sub-issue grouping is always intra-repo — Milestones never span Projects — so the unresolved cross-owner sub-issue restriction (BigscreenVR vs SaberMage) never applies. The cost is losing GitHub's native milestone progress view in the browser, which is immaterial when the working surface is Discord and the shell, and `subIssuesSummary` replaces it. The Milestone is the forward-looking plan (created at Greenlit, before code) and `fixes #N` is the completion signal; unifying them under one issue means the plan is itself the thing a release closes.
