Skip to content

MILESTONES.md template

The template the bootstrap agent (core/prompts/00-bootstrap.md) copies into a consumer repo. <<PLACEHOLDER>> tokens are replaced from Phase-1 spec reading and Phase-2 calibration answers.

MILESTONES.md
> **Template note (delete this block on first commit).**
> This is the schedule of acceptance. Phases are sequenced by *dependency*,
> not by excitement. Each phase has an explicit acceptance gate, a
> verification round, and a handoff. Friction surfaced in a closed phase's
> verification round becomes the *next* phase's input — never a retrofit.
>
> Milestone IDs follow `M{phase}.{subphase}.{nested?}`. Nested numbering
> (e.g. `M7.2.1`) exists specifically to host friction carry-overs from
> a previous phase, so the lineage stays legible.
---
## Phase index
| Phase | Title | Status | Acceptance summary |
| ----- | -------------------------- | ------------- | --------------------------------------------------------- |
| 1 | <<PHASE_1_TITLE>> | `next` | <<PHASE_1_ACCEPTANCE_ONELINER>> |
| 2 | <<PHASE_2_TITLE>> | `not-started` | <<PHASE_2_ACCEPTANCE_ONELINER>> |
| 3 | <<PHASE_3_TITLE>> | `not-started` | <<PHASE_3_ACCEPTANCE_ONELINER>> |
| 4 | <<PHASE_4_TITLE>> | `not-started` | <<PHASE_4_ACCEPTANCE_ONELINER>> |
| 5 | <<PHASE_5_TITLE>> | `not-started` | <<PHASE_5_ACCEPTANCE_ONELINER>> |
| 6 | <<PHASE_6_TITLE>> | `not-started` | <<PHASE_6_ACCEPTANCE_ONELINER>> |
| ... | | | |
**Status legend:** `not-started` · `next` · `open` · `closed` · `frozen` · `superseded`.
**Closed** means acceptance gate met *and* verification round complete *and* handoff doc written. Anything less is `open`.
---
## Active phase
Phase **<<ACTIVE_PHASE_NUM>>** — <<ACTIVE_PHASE_TITLE>> · status `<<ACTIVE_PHASE_STATUS>>`.
Open since: `<<ISO_DATE>>` (see `docs/decisions/<<ISO_DATE>>-phase-<<ACTIVE_PHASE_NUM>>-open.md`).
---
## Phase 1 — <<PHASE_1_TITLE>>
**Status:** `next`
**Why this phase first:** <<DEPENDENCY_JUSTIFICATION>>
**Spec anchor:** <<SPEC_DOC_PATHS_AND_SECTIONS>>
### Entry criteria
Before opening this phase, all of these must hold:
- [ ] <<ENTRY_CRITERION_1>>
- [ ] <<ENTRY_CRITERION_2>>
- [ ] Bootstrap decision doc exists (`docs/decisions/YYYY-MM-DD-bootstrap-complete.md`).
- [ ] `AGENTS.xml` validates and includes the subagents this phase will spawn.
### Subphases
#### M1.1 — <<SUBPHASE_1_1_TITLE>>
- **Goal:** <<GOAL>>
- **Owns:** <<FILES_OR_MODULES_TOUCHED>>
- **Reads:** <<SPEC_OR_PRIOR_ARTEFACTS>>
- **Acceptance check:** <<CONCRETE_CHECK_eg_TESTS_PASS_OR_INVARIANT_HOLDS>>
- **Subagent:** `implementer` → handoff to `auditor`
#### M1.2 — <<SUBPHASE_1_2_TITLE>>
- **Goal:** <<GOAL>>
- **Owns:** <<FILES_OR_MODULES>>
- **Acceptance check:** <<CHECK>>
- **Subagent:** `implementer``auditor`
### Phase 1 acceptance gate
The phase closes only when **all** of these hold, evidenced in the phase-close decision doc:
1. **<<ACCEPTANCE_GATE_1>>** — concrete check, e.g. *"`make e2e` exits 0 and `tests/integration/test_<<KEY_FLOW>>.py` covers the happy path + 2 failure modes"*.
2. **<<ACCEPTANCE_GATE_2>>** — e.g. *"the contract schema at `<<SCHEMA_PATH>>` is published and frozen — no breaking changes from this phase forward without a decision doc"*.
3. **<<ACCEPTANCE_GATE_3>>** — e.g. *"invariant I-N holds under the soak harness; evidence in `docs/decisions/YYYY-MM-DD-phase-1-evidence.md`"*.
4. Verification round complete (see below).
### Verification round (mandatory)
After acceptance gates 1–3 pass, before declaring `closed`, run `prompts/03-verification-round.md`. The round produces a `friction-budget` section in the phase-close decision doc, classifying every surfaced item as:
- **closed** — fixed within this phase (only allowed for trivial follow-ups, e.g. typo, broken link).
- **in-budget** — acceptable carry; documented and accepted.
- **deferred to phase N+1 as M(N+1).x.y** — written into MILESTONES.md *in the same commit* as the phase-close decision doc.
If you find yourself wanting to extend the phase to fix friction surfaced in its own verification round: **don't.** That's the anti-pattern. Defer to the next phase.
### Handoff to phase 2
Phase-close decision doc (`docs/decisions/YYYY-MM-DD-phase-1-close.md`) must hand to phase 2:
- the artefacts phase 2 needs to read,
- any deferred milestones (`M2.X.Y` IDs),
- updated invariant numbers (if phase 1 introduced any),
- subagent roster updates (if any).
---
## Phase 2 — <<PHASE_2_TITLE>>
**Status:** `not-started`
**Depends on:** Phase 1 closed.
**Spec anchor:** <<SPEC_PATHS>>
### Entry criteria
- [ ] Phase 1 status = `closed`.
- [ ] Phase 1 phase-close decision doc exists and lists this phase's required preconditions as met.
- [ ] <<PHASE_SPECIFIC_ENTRY_1>>
### Subphases
#### M2.1 — <<SUBPHASE_TITLE>>
*(same shape as M1.1)*
### Phase 2 acceptance gate
*(same shape as Phase 1)*
### Verification round
*(same shape as Phase 1)*
### Handoff to phase 3
*(same shape)*
---
## Phase 3, 4, 5, ... — <<TITLES>>
*(generated using the same shape; status `not-started` until their predecessors close)*
---
## Cross-phase invariants (drawn from `CLAUDE.md`)
These hold *across all phases*. A phase that violates one of these does not close, regardless of acceptance gate status:
- **I-1.** <<INVARIANT_1>>
- **I-2.** <<INVARIANT_2>>
- **I-3.** <<INVARIANT_3>>
- *(extend; keep numbered identically to `CLAUDE.md`)*
## Frozen / superseded phases
Anything that was `next` or `open` and got cancelled or superseded lives here with a one-line reason and a pointer to the decision doc that killed it. **Don't delete superseded phases** — the lineage is part of the system's memory.
- *(none yet)*
## How to read this file as a fresh agent
1. Look at **Phase index** to see where the project is.
2. Read the **Active phase** block + its subphases — that's your work surface.
3. Check **Cross-phase invariants** — those bind regardless of which phase you're in.
4. If you're about to start work, read `AGENTS.xml` for which subagent owns the subphase. If you're about to close a phase, read the **Verification round** subsection above and `prompts/02-phase-close.md`.