Files
Claude-Code-Game-Studios/CCGS Skill Testing Framework/skills/readiness/story-done.md
T
DonchitosandClaude Opus 5.5 b21fa0f7f2 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
2026-09-29 21:32:19 +10:00

19 KiB
Raw Blame History

Skill Test Spec: /story-done

Skill Summary

/story-done closes the loop between design and implementation. Run at the end of implementing a story, it reads the story file, re-reads the current requirement text from docs/architecture/tr-registry.yaml (never the story's quoted copy) and the governing ADR's ## Decision / ## Consequences, verifies each acceptance criterion (automatically, by batched AskUserQuestion, or as DEFERRED — requires playtest session), builds a criterion-to-test traceability table, checks test evidence, and checks GDD/ADR/manifest/scope deviations (categorised BLOCKING / ADVISORY / OUT OF SCOPE). Review mode then decides the QA coverage gate (QL-TEST-COVERAGE) and the code review step (LP-CODE-REVIEW in full, a /code-review question in lean, a noted skip in solo). It produces a COMPLETE / COMPLETE WITH NOTES / NOT ASSESSED / BLOCKED verdict and, only after an AskUserQuestion choice, updates the story file, optionally appends to docs/tech-debt-register.md, and surfaces the next story — with no sprint plan, from bash .claude/scripts/story-status.sh, the list /help and /sprint-status read, run after the story file is written. It says what a screenshot shows only after opening it, and asks about behaviour criteria rather than reading them off the code.


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 ≥5 phase headings (complex multi-phase skill)
  • Contains verdict keywords: COMPLETE, COMPLETE WITH NOTES, NOT ASSESSED, BLOCKED
  • allowed-tools includes Write/Edit, so ask-before-write language is present ("Use AskUserQuestion before writing anything" — covering the story file and the tech-debt register)
  • Has a next-step handoff (surfaces next story from sprint)

Test Cases

Case 1: Happy Path — All acceptance criteria met, no deviations

Fixture:

  • project.yaml sets modes.rigor: standard (→ workflow: standard, qa.level: standard, review_mode: lean) and engine.name: Godot, so tests/unit/ is the test root
  • Story file at production/epics/core/story-light-pickup.md with:
    • Type: Logic and 3 acceptance criteria, all implemented as described: AC-1 "Picking up a light adds it to the inventory", AC-2 "A pickup at the carry limit is refused", AC-3 "The picked-up light leaves the world"
    • TR-light-001; the story quotes an older wording of the requirement, while tr-registry.yaml holds the current text, which the implementation matches
    • ADR: ADR-0003 (Accepted), whose guidance was followed
    • A ## Test Evidence section naming tests/unit/light/pickup_test.gd, which exists with one test per criterion — test_pickup_adds_to_inventory, test_pickup_refused_at_limit, test_pickup_removes_world_light — so every criterion maps to a test
    • Status: In Progress
  • The /dev-story checkpoint in production/session-state/active.md names this story as Current task and carries Run result: OBSERVED — the light leaves the floor and the inventory count rises — production/qa/evidence/story-light-pickup/01-pickup.png; that image exists
  • Implementation files listed in the story exist in the code root
  • A sprint plan in production/sprints/ has other READY / NOT STARTED Must Have stories

Input: /story-done production/epics/core/story-light-pickup.md

Expected behavior:

  1. Skill reads the story and extracts its fields
  2. Skill greps tr-registry.yaml for TR-light-001 and uses that current text
  3. Skill maps the ADR's headings and reads only ## Decision and ## Consequences
  4. Skill verifies each criterion and builds the traceability table: AC-1..AC-3 each map to their test function, all COVERED
  5. Test evidence found — reported as "Test file present at <path>" (existence, not a pass claim); the checkpoint's Run result: OBSERVED is noted with its retained path
  6. No deviations
  7. Phase 4b notes "QL-TEST-COVERAGE skipped — Lean mode."
  8. Phase 5 (lean) asks "Code review is skipped in lean mode. Did you run /code-review on the implemented files?"
  9. Completion report with verdict COMPLETE
  10. AskUserQuestion "Verification complete. How do you want to proceed?"; on "Close the story", the file is updated
  11. Skill surfaces the next ready stories from the sprint

Assertions:

  • Requirement text comes from tr-registry.yaml, not the story's stale quote — the wording difference produces no deviation
  • Skill reads only the ADR's ## Decision and ## Consequences spans, not the whole file
  • Each criterion is listed with its status (auto-verified / confirmed / FAILS / DEFERRED) and appears in a Criterion | Test | Status traceability table
  • Test evidence is reported as present, without claiming the tests pass
  • In lean mode the skill asks whether /code-review was run, and records the answer in the Completion Notes Code Review: line
  • The traceability table maps each of AC-1..AC-3 to its test function, with no UNTESTED row
  • The Run result: line is read from the checkpoint (whose Current task names this story) and noted with its retained path
  • Verdict is COMPLETE — every criterion maps to a test, the run was observed and retained, and no deviations exist
  • No file is edited before the Phase 7 AskUserQuestion; on "Close the story" the story gets Status: Complete, a Last Updated: date and a ## Completion Notes section
  • After completion, skill surfaces the next READY / NOT STARTED Must Have or Should Have story from production/sprints/ and suggests /story-readiness [path]

Case 2: Criteria needing manual or playtest verification

Fixture:

  • As Case 1, plus two more criteria:
    • (a) "Player sees correct animation on pickup" — no automated test; a frame of the animation is retained at production/qa/evidence/story-light-pickup/02-pickup-anim.png
    • (b) "Pickup state persists across a full level run" — needs a full game build
  • 1 of the 5 criteria ends up with no covering test

Input: /story-done production/epics/core/story-light-pickup.md

Expected behavior:

  1. Criterion (a) is a subjective/gameplay criterion → skill asks via a batched AskUserQuestion ("Does [criterion]?" — Yes — passes / No — fails / Not tested yet)
  2. The user answers Yes — passes. The retained frame is the observation the evidence rule requires; the answer covers the motion a still cannot show, and counts as the manual test
  3. Criterion (b) is marked DEFERRED — requires playtest session and does not block
  4. The traceability table shows (b) UNTESTED; 1 of 5 (≤50%) → ADVISORY
  5. The Completion Notes list the deferred item and "Untested criteria: [AC-N list]. Recommend adding tests in a follow-up story."

Assertions:

  • Skill asks the user about the unverifiable criterion rather than assuming it passes, batching up to 4 such questions per call — a behaviour criterion is never marked verified from reading the code
  • Before the report says what 02-pickup-anim.png shows, the image is opened with Read; the checkpoint's Run result: text is quoted as /dev-story's description, never restated as the skill's own observation
  • The playtest-only criterion is marked DEFERRED — requires playtest session
  • Verdict is COMPLETE WITH NOTES, and the report lists the DEFERRED criterion — neither BLOCKED nor NOT ASSESSED, since a DEFERRED criterion does not block and does not fire the NOT ASSESSED trigger
  • The deferred criterion is named in the Completion Notes Criteria: line, with the untested-criteria recommendation
  • Variant — if the user answers No — fails for (a), the criterion is FAILS, the verdict is BLOCKED, and the skill does not proceed to Phase 7 on its own
  • Variant — no image for this story is retained under production/qa/evidence/ and the checkpoint carries no Run result: line: the user's Yes — passes for (a) is an assertion, not evidence, so the missing observation is flagged at the Logic gate level (BLOCKING by default) and the verdict is BLOCKED — never COMPLETE WITH NOTES on the confirmation alone
  • Skill still asks via AskUserQuestion before updating the story file

Case 3: Blocked Path — GDD deviation detected

Fixture:

  • project.yaml sets modes.workflow: full
  • The current tr-registry.yaml text for the story's TR-ID: "Player can carry max 3 light sources"
  • Implementation in the code root has MAX_CARRIED_LIGHTS = 5 in gameplay code

Input: /story-done production/epics/core/story-light-pickup.md

Expected behavior:

  1. The GDD rules check (against the current registry text) finds the implementation contradicts "max 3"
  2. The hardcoded-values check also flags the gameplay literal that belongs in a data file
  3. The contradiction is categorised BLOCKING and cited with its GDD/TR reference
  4. Verdict BLOCKED; skill lists what must be fixed and offers to help, and does not advance to Phase 7 on its own
  5. If the user explicitly asks to close anyway, the Phase 7 menu appears (always asked, even in autonomous mode — scope_changes)

Assertions:

  • Skill detects the mismatch between the current requirement text and the implemented value
  • The deviation is reported neutrally as BLOCKING with the GDD/TR reference — the skill does not edit code or the GDD to reconcile it
  • Verdict is BLOCKED, and Phase 7 is not entered unless the user explicitly asks to close anyway
  • Closing a BLOCKED story goes through the Phase 7 AskUserQuestion regardless of automation mode
  • If closed via "Accept deviations as-is and close anyway", the deviation is recorded in the Completion Notes Deviations: line

Case 4: Edge Case — No argument, auto-detect current story

Fixture:

  • production/session-state/active.md names production/epics/core/story-oxygen-drain.md as the active story
  • That story file exists with Status: In Progress

Input: /story-done (no argument)

Expected behavior:

  1. Skill reads production/session-state/active.md and takes the active story
  2. Skill reads that story file and proceeds normally
  3. The completion report's **Story**: line names the auto-detected path
  4. If active.md names no story, skill reads the newest sprint plan for IN PROGRESS stories; with several, it asks "Which story are we completing?"; with none, it asks for the path

Assertions:

  • Skill reads production/session-state/active.md first when no argument is given
  • The report's **Story**: line names the auto-detected story file
  • With several in-progress stories in the sprint, skill asks which one via AskUserQuestion instead of picking one
  • If no story is found anywhere, skill asks the user to provide a path

Case 5: Director Gate — LP-CODE-REVIEW across review modes

Fixture:

  • project.yaml sets modes.workflow: full and qa.level: standard (so the QA coverage gate is not skipped for qa.level: minimal)
  • Story file at production/epics/core/story-light-pickup.md, Type: Logic
  • All acceptance criteria verified, no GDD deviations, implementation files exist, and Case 1's run evidence (the Run result: OBSERVED checkpoint and its retained image)
  • Review mode comes from modes.review_mode (legacy mirror production/review-mode.txt) or --review

Case 5a — full mode: /story-done production/epics/core/story-light-pickup.md --review full

Expected behavior:

  1. After Phases 3–4, skill spawns qa-lead with gate QL-TEST-COVERAGE (unless qa.level: minimal or a Config/Data story)
  2. Skill spawns lead-programmer with gate LP-CODE-REVIEW, passing the implementation file paths, story path, relevant GDD section and governing ADR
  3. The verdict (APPROVE / CONCERNS / REJECT) is presented to the user
  4. CONCERNS → AskUserQuestion: Revise flagged issues / Accept and proceed / Discuss further
  5. REJECT → no Phase 6 verdict until the issues are resolved
  6. NOT ASSESSED (a gate input was missing) → the skill names the missing input and never reads it as APPROVE: the input is supplied and the gate re-run, or the Phase 6 verdict is at best NOT ASSESSED

Assertions (5a):

  • Skill uses the resolved review mode before deciding whether to spawn LP-CODE-REVIEW
  • LP-CODE-REVIEW is spawned in full mode after the implementation checks, with the four context items
  • A REJECT verdict prevents the story from reaching a COMPLETE verdict until resolved
  • A CONCERNS verdict produces the three-option AskUserQuestion
  • A NOT ASSESSED answer from either gate is never treated as APPROVE / ADEQUATE: unless the missing input is supplied and the gate re-run, the verdict is NOT ASSESSED, not COMPLETE
  • Skill still asks via the Phase 7 AskUserQuestion before updating story status, even after APPROVE

Case 5b — lean mode: --review lean

Assertions (5b):

  • LP-CODE-REVIEW does NOT spawn
  • Skill asks "Did you run /code-review on the implemented files?" with the three listed options; all three proceed
  • "QL-TEST-COVERAGE skipped — Lean mode." is noted

Case 5c — solo mode: --review solo

Assertions (5c):

  • Neither LP-CODE-REVIEW nor QL-TEST-COVERAGE spawns, and no code-review question is asked
  • Output notes "LP-CODE-REVIEW skipped — Solo mode." and "QL-TEST-COVERAGE skipped — Solo mode."
  • Skill still requires the Phase 7 AskUserQuestion before marking the story Complete

Case 6: UI story at minimal, no sprint plan — the screenshot closes it

Fixture:

  • project.yaml sets modes.rigor: minimal (→ workflow: minimal, qa.level: minimal, review_mode: solo); there is no sprint plan in production/sprints/ — the brief's build order is the plan
  • production/epics/mvp/ holds story-001-*.md (Status: Complete), this story story-002-shop-panel.md (Status: In Progress) and story-003-*.md (Status: Ready)
  • story-002-shop-panel.md has Type: UI and two criteria: "The shop panel shows all 6 item slots inside the frame at 1280x720" and "Each slot shows its price"
  • production/qa/evidence/story-002-shop-panel/01-shop-open.png exists and shows both; the checkpoint carries Run result: OBSERVED with that path; there is no evidence doc and no sign-off

Input: /story-done production/epics/mvp/story-002-shop-panel.md

Expected behavior:

  1. At qa.level: minimal the Logic, Integration and Config/Data evidence checks, the >50%-untested escalation and Phase 4b are skipped ("QL-TEST-COVERAGE skipped — qa.level minimal.") — but the UI screenshot check runs
  2. The retained screenshot satisfies the UI gate; no evidence doc or sign-off is asked for
  3. Phase 4 runs the manifest, hardcoded-value and scope checks only (no GDD/ADR traceability at minimal); Phase 5 notes "LP-CODE-REVIEW skipped — Solo mode."
  4. Verdict COMPLETE; after the Phase 7 approval the story is marked Complete
  5. Phase 8 takes the no-sprint branch: it runs bash .claude/scripts/story-status.sh after the story file is written; story-003 is on its first TODO line → "Run /dev-story [path]"

Assertions:

  • The UI screenshot check runs at qa.level: minimal and is satisfied by the retained image alone — no evidence doc or sign-off is required for a UI story
  • Verdict is COMPLETE, not BLOCKED for a missing sign-off
  • Phase 8 names story-003 and recommends /dev-story directly — no /story-readiness line at minimal, and no Sprint Close-Out Sequence
  • The next story comes from bash .claude/scripts/story-status.sh, run after this story's Status: Complete is written — not from a grep of one epic folder
  • Variant — production/epics/combat/story-001-arena.md reads **Status:** In Review: it is Next Up (the script lists IN_REVIEW first, across every epic folder), and the Next Up line recommends /story-done [path] to close it, not /dev-story
  • Variant — no image under production/qa/evidence/ and no Run result: line: the UI gate is still BLOCKING at qa.level: minimal, so the verdict is BLOCKED
  • Variant — story-003 is Blocked, naming its blocker, and no other story is unfinished: Phase 8 prints no Next Up, names story-003 with its blocker, suggests clearing it, and never says the build order is done

Case 7: NOT ASSESSED — a criterion nobody could evaluate

Fixture:

  • As Case 1, plus a fourth criterion, AC-4: "The pickup code is robust" — it names no observable outcome, so no test, run or playtest could settle it

Input: /story-done production/epics/core/story-light-pickup.md

Expected behavior:

  1. AC-1..AC-3 verify as in Case 1
  2. AC-4 cannot be evaluated at all — not DEFERRED (no session could settle it as written) and not failed
  3. Verdict NOT ASSESSED, naming AC-4 and what would make it checkable (rewrite it as an observable condition)
  4. The skill does not proceed to Phase 7 on its own

Assertions:

  • Verdict is NOT ASSESSED — not COMPLETE or COMPLETE WITH NOTES, and not BLOCKED (nothing is known to fail)
  • Output names AC-4, why it cannot be evaluated, and what would make it checkable
  • Phase 7 is entered only if the user explicitly asks to close anyway; it then always prompts (scope_changes), and the Completion Notes record AC-4 as never evaluated
  • Variant — AC-4 is a checkable criterion that the user answers Not tested yet: it is UNTESTED in the traceability table and the verdict is NOT ASSESSED, naming what would settle it
  • Variant — another criterion also FAILS: the verdict is BLOCKED (BLOCKED is evaluated before NOT ASSESSED)

Protocol Compliance

  • Asks via AskUserQuestion before updating the story file
  • Appends to docs/tech-debt-register.md only when the user picks "Close and log advisory deviations as tech debt", as rows of /tech-debt's register table with an Added date — never as free bullets
  • Presents the complete report (criteria, traceability, test evidence, deviations, scope) before asking
  • Ends by surfacing the next ready story (sprint plan) or the next story in the epic folder (no sprint plan)
  • Never closes a BLOCKED or NOT ASSESSED story on its own — only on the user's explicit request, through Phase 7
  • Never skips code review silently: full spawns LP-CODE-REVIEW, lean asks, solo notes the skip

Coverage Notes

  • The full 8-phase flow of the skill is exercised across Cases 1-3; not all edge cases within each phase are covered.
  • Tech debt logging (docs/tech-debt-register.md) is covered only through the Phase 7 option and the row-format line in Protocol Compliance; no case writes a row.
  • The production/sprint-status.yaml update and the session-state checkpoint (both silent, after the Phase 7 approval) are not primary assertions.
  • Case 6 covers the no-sprint-plan branch at minimal; the Sprint Close-Out Sequence is not tested here.
  • Stories with multiple TR-IDs or multiple ADRs are not explicitly tested.