Release 1.1.2 — the default path works end to end

Fix release for 1.1.1: the minimal path end to end, engine commands that
run on Godot, Unity and Unreal, hook warnings you can see, and verdicts
that say when they could not check. Details in CHANGELOG.md; upgrade
steps in UPGRADING.md (v1.1.1 → v1.1.2).

Fixes #67
Fixes #131

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
This commit is contained in:
Donchitos
2026-09-29 21:32:19 +10:00
co-authored by Claude Opus 5.5
parent 7ed2c3e9c4
commit b21fa0f7f2
383 changed files with 22888 additions and 10618 deletions
@@ -2,170 +2,284 @@
## Skill Summary
`/milestone-review` generates a comprehensive review of a completed milestone:
what shipped, velocity metrics, deferred items, risks surfaced, and retrospective
seeds. In full mode the PR-MILESTONE director gate runs after the review is
compiled (producer reviews scope delivery). In lean and solo modes the gate is
skipped. The skill asks "May I write to `production/milestones/review-milestone-N.md`?"
before persisting. Verdicts: MILESTONE COMPLETE or MILESTONE INCOMPLETE.
`/milestone-review` reviews a milestone's progress from its definition in
`production/milestones/` (when one exists) and the sprint reports in
`production/sprints/`: feature completeness, quality metrics, code health, risk,
velocity, scope recommendations and a Go/No-Go recommendation (NOT ASSESSED /
GO / CONDITIONAL GO / NO-GO). Blocked stories and their blockers come from
`production/sprint-status.yaml` and the story files, open bugs from
`production/qa/bugs/`. Before producing any report it records each input as
FOUND or ABSENT; a section whose inputs are absent reads
`NOT ASSESSED — NO DATA`, and if every required input is absent it stops with
that as the whole verdict. In full review mode it spawns `producer` with the
PR-MILESTONE gate before the Go/No-Go recommendation is generated; the
producer's verdict (ON TRACK / AT RISK / OFF TRACK) is shown inline, and AT RISK
or OFF TRACK raises an `AskUserQuestion` on how to frame the recommendation. In
lean and solo modes the gate is skipped with a note. The skill asks "May I write
this to `production/milestones/[milestone-name]-review.md`?" before persisting.
Verdicts: COMPLETE (review saved), BLOCKED (write declined), or
`NOT ASSESSED — NO DATA` (no inputs at all).
---
## Static Assertions (Structural)
Verified automatically by `/skill-test static` — no fixture needed.
Checked against the SKILL.md by `/skill-test spec` — no fixture needed.
- [ ] Has required frontmatter fields: `name`, `description`, `argument-hint`, `user-invocable`, `allowed-tools`
- [ ] Has ≥2 phase headings
- [ ] Contains verdict keywords: MILESTONE COMPLETE, MILESTONE INCOMPLETE
- [ ] Contains verdict keywords: COMPLETE, BLOCKED, NOT ASSESSED
- [ ] Contains Go/No-Go recommendation values: GO, CONDITIONAL GO, NO-GO
- [ ] Contains "May I write" language (skill writes review document)
- [ ] Has a next-step handoff (what to do after review is written)
- [ ] Has a next-step handoff (`/gate-check`, `/sprint-plan`)
---
## Director Gate Checks
| Gate ID | Trigger condition | Mode guard |
|---------------|--------------------------------|-------------------------|
| PR-MILESTONE | After review document compiled | full only (not lean/solo) |
| Gate ID | Trigger condition | Mode guard |
|---------------|------------------------------------------------|---------------------------|
| PR-MILESTONE | Before the Go/No-Go recommendation is generated | full only (not lean/solo) |
PR-MILESTONE verdicts: ON TRACK / AT RISK / OFF TRACK — or NOT ASSESSED
[missing input] (`.claude/docs/director-gates.md`), on which the skill never
recommends GO.
---
## Test Cases
### Case 1: Happy Path — Nearly complete milestone with one deferred story
### Case 1: Happy Path — Nearly complete milestone with one deferred feature
**Fixture:**
- `production/milestones/milestone-03.md` exists with 8 stories
- 7 stories have `Status: Complete`
- 1 story has `Status: Deferred` (deferred to milestone-04)
- `review-mode.txt` contains `full`
- `production/milestones/milestone-03.md` exists (milestone-definition template)
with 8 features in its Feature List
- 7 features have `Status: Complete`
- 1 feature has `Status: Deferred` (deferred to milestone-04)
- `production/sprints/sprint-007.md` through `sprint-009.md` exist with the
headings `/sprint-plan` writes
- The features' stories exist under `production/epics/`; none is `Blocked`
- `project.yaml` sets `modes.review_mode: full`
- The producer returns ON TRACK
**Input:** `/milestone-review milestone-03`
**Expected behavior:**
1. Skill reads `milestone-03.md` and all referenced sprint files
2. Skill compiles: 7 shipped, 1 deferred; velocity; no blockers
3. Skill presents review draft to user
4. PR-MILESTONE gate invoked; producer approves
5. Skill asks "May I write to `production/milestones/review-milestone-03.md`?"
6. User approves; file is written; verdict MILESTONE COMPLETE
1. Skill reads `milestone-03.md`, globs the sprint reports (N = 3) and greps
their sections, then greps the story files for Blocked statuses (none)
2. Skill compiles the review: 7 features under Fully Complete; the deferred
feature is not counted as complete
3. Skill spawns `producer` with PR-MILESTONE, passing milestone name and target
date, completion percentage, blocked story count (0), velocity data and cut
candidates
4. The producer's ON TRACK verdict is shown inline in the Go/No-Go section; no
framing question is asked
5. Skill presents the review and asks "May I write this to
`production/milestones/milestone-03-review.md`?"
6. User approves; file is written; verdict COMPLETE
**Assertions:**
- [ ] Deferred story is noted in the review with its target milestone
- [ ] Verdict is MILESTONE COMPLETE despite the one deferred story
- [ ] PR-MILESTONE gate is invoked after draft compilation in full mode
- [ ] Skill asks "May I write" before writing review file
- [ ] Review document path matches `production/milestones/review-milestone-03.md`
- [ ] The deferred feature is not listed under Fully Complete and is not counted as complete in the completion percentage (7 of 8)
- [ ] PR-MILESTONE is spawned in full mode before the Go/No-Go recommendation, with completion percentage and blocked story count passed
- [ ] The producer's ON TRACK verdict appears inline in the Go/No-Go section, and no framing `AskUserQuestion` is raised (only AT RISK and OFF TRACK raise one)
- [ ] Skill asks "May I write" before writing, naming `production/milestones/milestone-03-review.md`
- [ ] Verdict is COMPLETE after the write
---
### Case 2: Blocked Milestone — Multiple blocked stories
### Case 2: Blocked Milestone — Producer returns OFF TRACK
**Fixture:**
- `production/milestones/milestone-03.md` exists with 5 stories
- 2 stories have `Status: Complete`
- 3 stories have `Status: Blocked` (named blockers listed in each story)
- `review-mode.txt` contains `full`
- `production/milestones/milestone-03.md` lists 5 features
- 2 features have `Status: Complete`
- 3 features have `Status: Blocked`; each has one story under
`production/epics/[its epic]/` whose file carries `> **Status**: Blocked` and
a `BLOCKED:` note naming its blocker
- Sprint reports exist in `production/sprints/`; they name no blockers
- `project.yaml` sets `modes.review_mode: full`
- The producer returns OFF TRACK
**Input:** `/milestone-review milestone-03`
**Expected behavior:**
1. Skill reads milestone and sprint files
2. Skill finds 3 blocked stories; compiles blocker details
3. Verdict is MILESTONE INCOMPLETE
4. PR-MILESTONE gate runs; producer notes the unresolved blockers
5. Review is written with blocker list on approval
1. Skill reads the milestone and sprint reports, then greps the story files for
`Blocked` statuses and `BLOCKED:` notes; compiles the 3 blocked features in
the Blocked table with their blockers
2. Skill spawns PR-MILESTONE, passing a completion percentage of 40% and a
blocked story count of 3
3. On OFF TRACK, skill asks via `AskUserQuestion`: "Producer verdict: OFF TRACK.
The milestone is in jeopardy. This review will recommend NO-GO. How do you
want to proceed?" with [A] Accept NO-GO, [B] Override to CONDITIONAL GO,
[C] Stop
4. User selects [A]; the Go/No-Go recommendation is NO-GO
5. Skill presents the review, asks "May I write", and writes on approval
**Assertions:**
- [ ] Verdict is MILESTONE INCOMPLETE when any stories are Blocked
- [ ] Each blocked story's name and blocker reason is listed in the review
- [ ] PR-MILESTONE gate is still invoked in full mode even for INCOMPLETE verdict
- [ ] "May I write" prompt still appears before file write
- [ ] Each blocked feature is named in the Blocked table with its blocker, taken from its story's `BLOCKED:` note — the sprint reports carry none, so a blocker not read from the story files is invented
- [ ] PR-MILESTONE receives the blocked story count (3), counted from the story files
- [ ] OFF TRACK raises the `AskUserQuestion` with Accept NO-GO / Override to CONDITIONAL GO / Stop before the recommendation is generated
- [ ] After [A], the recommendation is NO-GO — the skill does not issue GO against an OFF TRACK verdict
- [ ] "May I write" prompt still appears before the file is written
---
### Case 3: Full Mode — PR-MILESTONE returns CONCERNS
### Case 3: Full Mode — PR-MILESTONE returns AT RISK over scope drift
**Fixture:**
- Milestone-03 has 6 complete stories but 2 were not in the original scope (added mid-sprint)
- `review-mode.txt` contains `full`
- `production/milestones/milestone-03.md` lists 6 complete features, 2 of which
were not in the original definition (added mid-milestone)
- Sprint reports exist in `production/sprints/`
- `project.yaml` sets `modes.review_mode: full`
- The producer returns AT RISK, citing the 2 added features as scope drift and
listing mitigations
**Input:** `/milestone-review milestone-03`
**Expected behavior:**
1. Skill compiles review; notes 2 out-of-scope stories shipped
2. PR-MILESTONE gate invoked; producer returns CONCERNS about scope drift
3. Skill surfaces the CONCERNS to the user and adds a "scope drift" note to the review
4. User approves revised review; file written as MILESTONE COMPLETE with caveat
1. Skill compiles the review
2. PR-MILESTONE returns AT RISK with mitigations
3. Skill asks via `AskUserQuestion`: "Producer verdict: AT RISK. Milestone may
slip. How should the Go/No-Go section be framed?" with [A] CONDITIONAL GO,
[B] NO-GO, [C] GO
4. User selects [A]; the Go/No-Go section reads CONDITIONAL GO and lists the
producer's conditions
5. Skill presents the review, asks "May I write", and writes on approval
**Assertions:**
- [ ] CONCERNS from PR-MILESTONE gate are shown to user before write
- [ ] Scope drift is explicitly noted in the written review document
- [ ] Verdict is MILESTONE COMPLETE (stories shipped) with CONCERNS annotation
- [ ] Skill does not suppress gate feedback
- [ ] The producer's AT RISK assessment, including its scope-drift finding, is shown inline in the Go/No-Go section — not suppressed
- [ ] AT RISK raises the `AskUserQuestion` with CONDITIONAL GO / NO-GO / GO before the file is written
- [ ] After [A], the recommendation is CONDITIONAL GO and its Conditions list carries the producer's conditions
- [ ] The review is written only after "May I write" is approved
---
### Case 4: Edge Case — No milestone file found for specified milestone
### Case 4: Edge Case — No milestone definition and no sprint data
**Fixture:**
- User calls `/milestone-review milestone-07`
- `production/milestones/milestone-07.md` does NOT exist
- `production/milestones/` does not exist
- `production/sprints/` does not exist
- `production/risk-register/` does not exist
- No source files exist under the code root
- No story files, no `production/sprint-status.yaml` and no `production/qa/bugs/`
- `project.yaml` sets `modes.review_mode: full`
**Input:** `/milestone-review milestone-07`
**Input:** `/milestone-review current`
**Expected behavior:**
1. Skill attempts to read `production/milestones/milestone-07.md`
2. File not found; skill outputs an error message
3. Skill suggests checking available milestones in `production/milestones/`
4. No gate is invoked; no file is written
1. Skill lists its inputs and records each as FOUND or ABSENT
2. Every required input is ABSENT, so the skill stops and reports
`NOT ASSESSED — NO DATA` as the whole verdict
3. The report names what was missing and where it comes from: sprint reports
are written by `/sprint-plan`; milestone definitions are authored by hand
from `.claude/docs/templates/milestone-definition.md`
4. No milestone definition is fabricated, no gate is spawned, no file is written
**Assertions:**
- [ ] Skill does not crash when milestone file is absent
- [ ] Output names the expected file path in the error message
- [ ] Output suggests checking `production/milestones/` for valid milestone names
- [ ] Verdict is BLOCKED (cannot review a non-existent milestone)
- [ ] Skill does not crash and does not fill the review template with estimated values
- [ ] Verdict is `NOT ASSESSED — NO DATA` — not GO and not COMPLETE
- [ ] Output names the missing inputs and where each comes from (`/sprint-plan` for sprint reports; the milestone-definition template for milestones)
- [ ] PR-MILESTONE is not spawned and no "May I write" prompt appears
---
### Case 5: Lean/Solo Mode — PR-MILESTONE gate skipped
**Fixture:**
- `production/milestones/milestone-03.md` exists with 5 complete stories
- `review-mode.txt` contains `solo`
- `production/milestones/milestone-03.md` lists 5 features, all `Status: Complete`
- Sprint reports exist in `production/sprints/`
- `production/qa/bugs/` does not exist — no bug has been filed with `/bug-report`
- `project.yaml` sets `modes.review_mode: solo`
**Input:** `/milestone-review milestone-03`
**Expected behavior:**
1. Skill reads review mode — determines `solo`
2. Skill compiles review draft
3. PR-MILESTONE gate is skipped; output notes "[PR-MILESTONE] skipped — Solo mode"
4. Skill asks user for direct approval of the review
5. User approves; review file is written; verdict MILESTONE COMPLETE
1. Skill reads `review_mode` from the injected config block — `solo`
2. Skill compiles the review; with no bug files, the Quality Metrics bug lines
read `NOT ASSESSED — NO DATA`
3. PR-MILESTONE is skipped; output notes "PR-MILESTONE skipped — Solo mode."
4. The Go/No-Go section is presented without a producer verdict
5. Skill asks "May I write this to `production/milestones/milestone-03-review.md`?"
6. User approves; review file is written; verdict COMPLETE
**Assertions:**
- [ ] PR-MILESTONE gate is NOT invoked in solo (or lean) mode
- [ ] Skip is explicitly noted in skill output
- [ ] User direct approval is still required before write
- [ ] Verdict is MILESTONE COMPLETE after successful write
- [ ] PR-MILESTONE gate is NOT invoked in solo mode
- [ ] Output contains "PR-MILESTONE skipped — Solo mode."
- [ ] The Go/No-Go section carries no producer verdict (no ON TRACK / AT RISK / OFF TRACK attributed to the producer)
- [ ] The Quality Metrics bug lines read `NOT ASSESSED — NO DATA` — not "0" — while the sections that have inputs are still produced
- [ ] User approval is still required before the write
- [ ] Verdict is COMPLETE after the write
---
### Case 6: Lean Mode from Rigor — PR-MILESTONE skipped with the Lean note
**Fixture:**
- `production/milestones/milestone-03.md` lists 4 features, all `Status: Complete`
- Sprint reports exist in `production/sprints/`
- `project.yaml` sets `modes.rigor: standard` and pins no review mode, so the
injected block reads `review_mode: lean (rigor:standard)`
**Input:** `/milestone-review milestone-03`
**Expected behavior:**
1. Skill reads `review_mode` from the injected config block — `lean`
2. Skill compiles the review
3. PR-MILESTONE is skipped; output notes "PR-MILESTONE skipped — Lean mode."
4. The Go/No-Go section is presented without a producer verdict
5. Skill asks "May I write", writes on approval; verdict COMPLETE
**Assertions:**
- [ ] PR-MILESTONE gate is NOT invoked in lean mode
- [ ] Output contains "PR-MILESTONE skipped — Lean mode." — not the Solo note
- [ ] The Go/No-Go section carries no producer verdict
- [ ] User approval is still required before the write, and the verdict is COMPLETE after it
---
### Case 7: Gate returns NOT ASSESSED — Never GO
**Fixture:**
- `production/milestones/milestone-03.md` lists 5 features, all `Status: Complete`,
but gives no Target Date
- Sprint reports exist in `production/sprints/`; the stories exist under
`production/epics/` and none is `Blocked`
- `project.yaml` sets `modes.review_mode: full`
- The producer returns NOT ASSESSED — no target date to judge against
- Asked for the date, the user has none to give
**Input:** `/milestone-review milestone-03`
**Expected behavior:**
1. Skill compiles the review and spawns PR-MILESTONE; it returns NOT ASSESSED
2. Skill names the missing input (the target date) and treats the result as
neither ON TRACK nor a reason to recommend GO
3. Nothing in the review's own findings calls for CONDITIONAL GO or NO-GO, so
the Go/No-Go recommendation reads NOT ASSESSED, naming the missing target date
4. Skill asks "May I write", writes on approval; verdict COMPLETE
**Assertions:**
- [ ] The Go/No-Go recommendation is NOT ASSESSED — never GO — although every feature is Complete
- [ ] The missing target date is named in the Go/No-Go section
- [ ] The AT RISK and OFF TRACK framing questions are not raised for NOT ASSESSED
- [ ] "May I write" still appears before the file is written
---
## Protocol Compliance
- [ ] Shows compiled review draft before invoking PR-MILESTONE or asking to write
- [ ] Always asks "May I write" before writing review document
- [ ] PR-MILESTONE gate only runs in full mode
- [ ] Skip message appears in lean and solo output
- [ ] Verdict is MILESTONE COMPLETE or MILESTONE INCOMPLETE, stated clearly
- [ ] Records each input as FOUND or ABSENT before producing a report; reports `NOT ASSESSED — NO DATA` when every required input is absent, and for any single section whose inputs are absent
- [ ] In full mode, spawns PR-MILESTONE before generating the Go/No-Go recommendation, and presents the complete review before asking to write
- [ ] Always asks "May I write" before writing the review document
- [ ] PR-MILESTONE gate only runs in full mode; the skip message appears in lean and solo output
- [ ] Verdict is stated clearly — COMPLETE, BLOCKED (write declined) or `NOT ASSESSED — NO DATA` — and the Go/No-Go recommendation is one of NOT ASSESSED / GO / CONDITIONAL GO / NO-GO
---
## Coverage Notes
- The case where the milestone has zero stories is not tested; it follows the
MILESTONE INCOMPLETE pattern with a note suggesting the milestone may not
have been planned.
- `production/milestones/` absent while sprint reports exist (the skill says so
and reviews against the sprint reports alone) is not tested.
- `current` selection skipping files that end `-review.md` is not tested.
- The declined-write path (verdict BLOCKED) is not tested.
- Velocity calculation specifics (story points vs. story count) are not
verified here; they are implementation details of the review compilation phase.