/sdlc:milestone-review
Generated from solutions/ontological/skills/milestone-review/SKILL.md.
Description
Section titled “Description”Given a milestone id (M-NNNN) or milestone file, assess its real status against its declared frontmatter status: walk its member tasks and related items to derive a grounded status and the concrete gaps / remaining work, then scan unclosed tasks and backlog items for related-but-unlinked work — bugs or gaps reported elsewhere. Reports read-only by default; corrects frontmatter drift on —fix or after asking. Use when asked to review or audit a milestone, check whether a milestone’s status is accurate, or find what’s left before closing it.
Allowed tools
Section titled “Allowed tools”ReadEditBashGlobGrepAgentAskUserQuestion
Source
Section titled “Source”Usage:
/sdlc:milestone-review <M-NNNN | path>— assess one milestone; report, then ask whether to apply any drift corrections./sdlc:milestone-review <...> --fix— apply the safe drift corrections without asking./sdlc:milestone-review <...> --read-only— report only; never mutate and never prompt.
References:
${CLAUDE_PLUGIN_ROOT}entities/milestone/definition.md— status enum, membership derivation, and the frontmattertasks:↔ body## Deliverablessync rule. Read once per project — it governs every skill that touches milestone files.
Project context (don’t re-derive every run):
-
Milestones live in
docs/planning/milestones/asM<NNNN>-<slug>.md. Status enum:open/{draft,planned,active},closed/{done,partial,superseded,abandoned}. -
Member tasks are the frontmatter
tasks:list of[[T-NNNN]]wikilinks; the body## Deliverablessection mirrors them. Tasks carry no milestone back-link — membership is one-directional, so real membership is derived by reading each member plus scanning for unlinked relatives. -
Tasks live in
docs/planning/tasks/; “unfinished” = a status that does NOT start withclosed/. Backlog lives indocs/planning/backlog/asB<NNNN>files — freeform ideas that may point at a milestone viarelated:or body text. -
Validate after any frontmatter edit; gate on the exit code, don’t pipe (see Notes):
${CLAUDE_PLUGIN_ROOT}cli/sdlc entities validate <path>
1. Resolve the milestone
Section titled “1. Resolve the milestone”If the argument is a path, use it. If it is an id, glob docs/planning/milestones/M<NNNN>*.md. On
no match or an ambiguous match, print ERROR reason="..." and stop. Read the frontmatter (status,
tasks, related, version, completion_note) and the body (Goal, Success criteria,
Deliverables).
2. Walk member tasks
Section titled “2. Walk member tasks”For each [[T-NNNN]] in tasks:, read the target task’s frontmatter and classify its status: done
(closed/done), other-closed (any other closed/*), in-progress (in-progress[/blocked]), ready
(open/ready), planning (planning/*), or missing (no file / broken wikilink). Note blocked tasks.
Trust the member statuses here — deep “did this actually ship” verification is /sdlc:task-review’s
job; only flag a done task that the body plainly contradicts.
3. Derive grounded status
Section titled “3. Derive grounded status”Map member reality to the milestone status the evidence supports:
- none started or all
planning/*, body still placeholder →open/draft. - committed, tasks queued, none started →
open/planned. - ≥1 member in-progress, OR mixed (some closed, some open) →
open/active. - all members
closed/doneAND success criteria met →closed/donecandidate (needsversion+completion_note; recommend, never auto-flip). - some members closed non-done with the rest done →
closed/partialcandidate.
Compare grounded vs declared and set a drift verdict. Declared closed/* while ≥1 member is still
open is drift (premature close) → recommend reopening to open/active.
4. Scan for related-but-unlinked work
Section titled “4. Scan for related-but-unlinked work”Grep docs/planning/tasks/ and docs/planning/backlog/ for the milestone id and its slug keywords.
Read the frontmatter of any hit not already in tasks:, and surface two buckets — this is where
bugs or gaps reported elsewhere show up:
- Unclosed tasks that reference or clearly belong to the milestone but aren’t members.
- Backlog items that reference the milestone or its theme.
Rank by relatedness, keep it to the top handful, and state plainly if you dropped weaker matches.
5. Report
Section titled “5. Report”Print inline, in this order:
- Header:
<id> — <title>, thenDeclared: <status> · Grounded: <status> · Drift: <yes|no>. - Member roster: one line per member task with its classified status; call out missing/blocked.
- Gaps / what remains: unmet success criteria plus every open member task.
- Related-but-unlinked candidates: the tasks and backlog items from step 4, each with a one-line why-related.
6. Correct drift
Section titled “6. Correct drift”If --read-only, skip to step 7 — no mutation, no prompt. Otherwise assemble the candidate
corrections:
status→ the groundedopen/*value. Do NOT auto-close: closing needsversion+completion_note, so only propose it and ask the user for those values.last_reviewed→ today (UTC); optionalrelevance_note→ one line on what shifted.- Append high-confidence unlinked member tasks to BOTH frontmatter
tasks:and the body## Deliverableslist (keep the two in sync). Backlog items are NOT tasks — never add them totasks:; recommend/sdlc:backlog-triageto promote them.
If --fix, apply the safe corrections directly. Otherwise, after the report, send one
AskUserQuestion (multiSelect) listing the proposed corrections and apply only the selected ones via
Edit.
7. Validate and report result
Section titled “7. Validate and report result”If anything was edited, run entities validate <path> and gate on its exit code (no pipe); fix and
re-run on failure. Then emit the terminal marker:
MILESTONE-REVIEW-OK: <id> declared=<s> grounded=<s> drift=<yes|no>— no edits.MILESTONE-REVIEW-FIXED: <id> status=<old>→<new> tasks+=<n>— edits applied.ERROR reason="..."— unrecoverable failure.
- Read-only by default: mutation happens only under
--fixor an explicit AskUserQuestion selection;--read-onlyforces a pure report. - Never auto-closes a milestone —
closed/donerequiresversion+completion_note(schema- enforced). Surface the close as a recommendation and let the user supply those. - Membership is one-directional: tasks carry no milestone back-link, so this skill reads every member and scans for unlinked relatives to ground the real state.
- Frontmatter ↔ Deliverables sync: appending a member task updates both
tasks:and the body## Deliverablesbullet — see${CLAUDE_PLUGIN_ROOT}entities/milestone/definition.md. - Backlog items are signal, not members: surface related ones and point at
/sdlc:backlog-triage; don’t fold them intotasks:. - Don’t pipe commands you gate on:
entities validatereturns a pipeline’s last exit code, so a piped| tailmasks a failure — see${CLAUDE_PLUGIN_ROOT}skills/CLAUDE.md.