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
14 KiB
Skill Test Spec: /sprint-plan
Skill Summary
/sprint-plan (new, update or status) plans a sprint from the story
backlog. It globs production/epics/**/story-*.md, greps their status lines and
plans from the stories marked Ready, as many as story_granularity allows; it
reads the previous sprint (identified from the injected Existing Sprints listing)
for velocity and carryover, and the milestone in production/milestones/ and
GDDs for context when they exist. For new it numbers the sprint one past the
highest sprint-NNN.md in the listing and presents a draft with Must Have /
Should Have / Nice to Have task tables and a Carryover from Previous Sprint table
(every not-Complete story of the previous sprint, listed there only) before any
write, and prepares production/sprint-status.yaml alongside it. The review
mode comes from the injected config block, --review overriding it for one run;
the skill never asks for one and never writes modes.review_mode or
production/review-mode.txt. In full review mode the PR-SPRINT producer gate
reviews the draft; in lean and solo modes the gate is skipped with a note. A QA
plan check runs in every mode. The skill asks "May I write the
sprint plan to production/sprints/sprint-NNN.md and
production/sprint-status.yaml?" before persisting. Verdicts: COMPLETE (both
files written) or BLOCKED (no stories found, or write declined).
Static Assertions (Structural)
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: COMPLETE, BLOCKED
- Contains "May I write" language (skill writes sprint file)
- Has a next-step handoff (
/qa-plan sprint,/story-readiness,/dev-story)
Director Gate Checks
| Gate ID | Trigger condition | Mode guard |
|---|---|---|
| PR-SPRINT | After the draft is presented, before write approval | full only (not lean/solo) |
PR-SPRINT verdicts: REALISTIC / CONCERNS / UNREALISTIC — or NOT ASSESSED
[missing input] (.claude/docs/director-gates.md), which is never treated as
REALISTIC.
Test Cases
Case 1: Happy Path — Ready backlog generates sprint
Fixture:
- The injected Existing Sprints listing shows
sprint-001.mdandsprint-002.md production/milestones/milestone-02.mdexists- 5 stories under
production/epics/across 2 epics haveStatus: Ready project.yamlsetsmodes.review_mode: fullandmodes.story_granularity: balanced(6–10 stories per sprint)production/qa/qa-plan-sprint-003.mdexists- The producer returns REALISTIC
Input: /sprint-plan new
Expected behavior:
- Skill reads the milestone and the previous sprint (sprint-002)
- Skill globs
production/epics/**/story-*.md, greps the status lines, and plans all 5Readystories — fewer thanbalancedallows, so the backlog is the limit - Skill numbers the new sprint 003 (sprint-002 is the highest in the listing) and presents the draft without asking to write
- Skill spawns PR-SPRINT with the story list, capacity, carryover and milestone constraints; presents the REALISTIC assessment
- QA plan check finds
production/qa/qa-plan-sprint-003.mdand notes it - Skill asks "May I write the sprint plan to
production/sprints/sprint-003.mdandproduction/sprint-status.yaml?" - User approves; both files are written; verdict COMPLETE
Assertions:
- Stories come from
production/epics/**/story-*.mdvia the status grep, and onlyReadystories are planned - All 5
Readystories are planned —balancedallows 6–10, so none is held back - Sprint draft is shown before any write prompt or gate invocation
- PR-SPRINT gate is invoked in full mode after the draft is presented
- "May I write" prompt names both
production/sprints/sprint-003.md(next after sprint-002) andproduction/sprint-status.yaml - Verdict is COMPLETE after both files are written
Case 2: Blocked Path — No stories in the backlog
Fixture:
production/epics/contains no story files (production/epics/**/story-*.mdmatches nothing)- No
--reviewflag, nomodes.review_modeinproject.yaml, noproduction/review-mode.txt
Input: /sprint-plan new
Expected behavior:
- Phase 0 takes the review mode from the injected config block — with nothing
configured, the
modes.rigorvalue — and asks no review-depth question - Phase 1's glob returns nothing; skill outputs "No stories found under
production/epics/. Run/create-storiesfirst (atstandard/full,/create-epicsbefore it)." - Skill stops without inventing work items; verdict BLOCKED
- No gate is invoked and nothing is written
Assertions:
- Verdict is BLOCKED
- Output contains "No stories found under
production/epics/" and recommends/create-stories - No sprint draft is produced from invented work items
- PR-SPRINT gate is NOT invoked
- No review-depth question is asked, and no write happens —
project.yamlgains nomodes.review_modeand noproduction/review-mode.txtis created
Case 3: Gate returns CONCERNS — Sprint overloaded, revised before write
Fixture:
- 8
Readystories estimated at 16 days in total; available capacity is 10 days project.yamlsetsmodes.review_mode: fullandmodes.story_granularity: balanced- A QA plan for the sprint exists in
production/qa/ - The producer returns CONCERNS: the sprint is overloaded
Input: /sprint-plan new
Expected behavior:
- Skill drafts the sprint with all 8 stories and presents it
- PR-SPRINT runs; producer returns CONCERNS
- Skill asks via
AskUserQuestion: "Producer flagged concerns with this sprint plan. How do you want to proceed?" with [A] Proceed as planned, [B] Adjust scope, [C] Extend the sprint timeline - User selects [B]; skill revises the story list and re-presents the plan
- Skill asks "May I write" for the revised plan; writes on approval
Assertions:
- CONCERNS from PR-SPRINT surfaces through
AskUserQuestion([A] Proceed / [B] Adjust scope / [C] Extend timeline) before any write - On [B], the revised plan is re-presented before write approval
- The revised sprint (not the original) is written, and
production/sprint-status.yamllists the revised stories - Verdict is COMPLETE after revision and write
Case 4: Lean Mode — PR-SPRINT skipped, QA plan check still runs
Fixture:
- 4
Readystories underproduction/epics/ project.yamlsetsmodes.rigor: standardand pins no review mode (nomodes.review_mode, noproduction/review-mode.txt, no--review), so the injected block readsreview_mode: lean (rigor:standard)- No QA plan for this sprint exists in
production/qa/
Input: /sprint-plan new
Expected behavior:
- Skill reads
review_modefrom the injected config block —lean— and asks no review-depth question - Skill drafts the sprint and presents it
- PR-SPRINT is skipped; output notes "PR-SPRINT skipped — Lean mode."
- The QA plan check still runs: skill states "This sprint has no QA plan …" and
asks via
AskUserQuestionwith [A] Run /qa-plan sprint now and [B] Skip for now - User selects [A]; skill asks for direct approval of the write
- User approves; both files are written; verdict COMPLETE
Assertions:
- PR-SPRINT gate is NOT invoked in lean mode
- Output contains "PR-SPRINT skipped — Lean mode."
- The QA plan check still runs in lean mode — the missing QA plan is surfaced explicitly with the [A]/[B] choice, not passed silently
- User approval is still required before the write (gate skip ≠ approval skip)
- The resolved
leanis used without a review-depth question, and the write names only the sprint plan andproduction/sprint-status.yaml—project.yamlgains nomodes.review_modeand noproduction/review-mode.txtis created - Verdict is COMPLETE after the write
Case 5: Edge Case — Previous sprint still has open stories
Fixture:
- The injected Existing Sprints listing shows
sprint-002.mdas the latest sprint production/sprint-status.yamlstill holds sprint 2; 2 of its stories are notdone: onein-progress, and oneready-for-devthat was never started (its story file saysStatus: Ready)- 5 other stories have
Status: Ready project.yamlsetsmodes.review_mode: fullandmodes.story_granularity: balanced- A QA plan for the sprint exists in
production/qa/
Input: /sprint-plan new
Expected behavior:
- Skill reads sprint-002 for velocity and carryover, and numbers the new sprint 003
- Skill plans the 5 other
Readystories in the Must Have / Should Have / Nice to Have tables - The 2 unfinished sprint-002 stories appear in the "Carryover from Previous
Sprint" table with a reason and a new estimate — the unstarted one there
only, although its story file says
Ready - The carryover is passed to PR-SPRINT with the proposed story list
- Skill asks "May I write the sprint plan to
production/sprints/sprint-003.mdandproduction/sprint-status.yaml?" and writes on approval; the new yaml lists the 2 carryover stories alongside the 5 new ones
Assertions:
- Skill reads the previous sprint (sprint-002, identified from the injected listing)
- The 2 unfinished stories appear in the "Carryover from Previous Sprint" table with Reason and New Estimate — not silently dropped
- The unstarted sprint-002 story appears only under Carryover — not again in Must Have / Should Have / Nice to Have, although its status is
Ready - The carryover is passed to the PR-SPRINT gate
- The written
production/sprint-status.yamllists the 2 carryover stories with their previous priority and current status (in-progress,ready-for-dev)
Case 6: Gate returns UNREALISTIC — Stories deferred before the write
Fixture:
- The injected Existing Sprints listing shows
sprint-002.mdas the latest sprint - 9
Readystories estimated at 20 days in total; available capacity is 10 days project.yamlsetsmodes.review_mode: fullandmodes.story_granularity: balanced- A QA plan for the sprint exists in
production/qa/ - The producer returns UNREALISTIC and names 4 stories to defer
Input: /sprint-plan new
Expected behavior:
- Skill drafts sprint 003 with the 9 stories and presents it
- PR-SPRINT runs; producer returns UNREALISTIC
- Skill revises the selection — the 4 named stories move down to Should Have or Nice to Have — and re-presents the revised plan
- The QA plan check runs, then skill asks "May I write" for the revised plan
- User approves; both files are written; verdict COMPLETE
Assertions:
- UNREALISTIC does not end the run, and the original plan is never written — the selection is revised first
- The 4 named stories are deferred to Should Have or Nice to Have, not dropped from the plan
- The revised plan is re-presented before the "May I write" prompt
- The written
production/sprint-status.yamlcarries the deferred stories asshould-haveornice-to-havewithstatus: backlog - Verdict is COMPLETE after the write
Case 7: Gate returns NOT ASSESSED — No story estimates
Fixture:
- 5
Readystories, none with itsEstimatefilled in project.yamlsetsmodes.review_mode: fullandmodes.story_granularity: balanced- A QA plan for the sprint exists in
production/qa/ - The producer returns NOT ASSESSED — the stories carry no estimates
- Asked for estimates, the user has none yet and goes ahead
Input: /sprint-plan new
Expected behavior:
- Skill drafts the sprint and presents it; PR-SPRINT returns NOT ASSESSED
- Skill names the missing input (story estimates) and does not treat the
result as REALISTIC; with no estimates to supply, it records PR-SPRINT as
NOT ASSESSED — [missing input]in the plan's header - The QA plan check runs; the "May I write" prompt repeats that PR-SPRINT was not assessed
- User approves; both files are written; verdict COMPLETE
Assertions:
- The missing input (story estimates) is named in the output
- NOT ASSESSED is not presented as REALISTIC — nothing says the plan's feasibility was reviewed
- The CONCERNS options ([A] Proceed / [B] Adjust scope / [C] Extend timeline) are not raised for NOT ASSESSED
- The written plan's header records PR-SPRINT as NOT ASSESSED with the missing input, and the "May I write" prompt says so before the write
Protocol Compliance
- Shows the draft sprint before invoking PR-SPRINT or asking to write
- Always asks "May I write" before writing, naming both the sprint file and
production/sprint-status.yaml - Never asks for a review depth and never writes
modes.review_modeorproduction/review-mode.txt— the resolved value (or--review) is used - PR-SPRINT gate only runs in full mode
- Skip message appears in lean and solo mode output
- The QA plan check runs in every review mode
- Verdict (COMPLETE or BLOCKED) is clearly stated at the end of the skill output
Coverage Notes
updateandstatusmodes are not tested.- No milestone file is not tested; the skill notes "no milestone defined — planning against the story backlog alone" and continues rather than blocking.
- Story files that exist with none marked
Readyare not tested. - Solo mode behavior is equivalent to lean (gate skipped, user approval required) and is not separately tested.
- The cases pin
story_granularitytobalanced(6–10 stories per sprint); thecoarse(2–4) andfine(15–25) allocations are not tested.