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
+132 -57
View File
@@ -1,6 +1,6 @@
---
name: dev-story
description: "Implement a story: ADR guidelines, right programmer agent, code plus test. After /story-readiness, before /code-review and /story-done."
description: "Implement a story: ADR guidelines, right programmer agent, code plus test. Then /story-done (/story-readiness before, /code-review after, at standard/full)."
argument-hint: "[story-path]"
user-invocable: true
disable-model-invocation: true
@@ -29,9 +29,12 @@ drives implementation to completion — including writing the test.
/story-done [path] ← verify and close it
```
**After all sprint stories are done:** run `/team-qa sprint` to execute the full QA cycle and get a sign-off verdict before advancing the project stage.
**At `workflow: minimal`** the loop is `/dev-story [path]` → `/story-done [path]`:
no QA plan, readiness check or sprint. `/story-done` names the next story.
**Output:** Source code under the project's **code root** + test file in `tests/`. Resolve the code root from `engine.name` (`src/` Godot, `Assets/` Unity, `Source/<Module>/` Unreal) per `.claude/docs/code-root-resolution.md`.
**With a sprint plan, after all sprint stories are done:** run `/team-qa sprint` to execute the full QA cycle and get a sign-off verdict before advancing the project stage.
**Output:** Source code under the project's **code root** + test file under the engine's **test root** (`tests/` Godot, `Assets/Tests/` Unity, `Source/<Module>/Private/Tests/` Unreal — `.claude/docs/directory-structure.md`). Resolve the code root from `engine.name` (`src/` Godot, `Assets/` Unity, `Source/<Module>/` Unreal) per `.claude/docs/code-root-resolution.md`.
---
@@ -48,8 +51,8 @@ project value. Resolve it at the start of Phase 2 (the story header is
read there) and apply it to the prerequisite gate.
**`story_granularity`** — it sets the
expected implementation cycle: **multi-day** at `coarse` (give the programmer
subagent longer working context), **1–2 days** at `balanced` (default), **hours**
expected implementation cycle: **multi-day** at `coarse` (the default, via `rigor: minimal`; give the programmer
subagent longer working context), **1–2 days** at `balanced` (`rigor: standard`), **hours**
at `fine` (tighter context). It does not change the prerequisite gate.
**`qa.level`**: controls whether the programmer brief carries
@@ -76,10 +79,10 @@ If not found, ask: "Which story are we implementing?" Glob
| File | Path | If missing — `full` | `standard` | `minimal` |
|------|------|---------------------|-----------|-----------|
| TR registry | `docs/architecture/tr-registry.yaml` | **STOP** — "TR registry not found at `docs/architecture/tr-registry.yaml`. Run `/architecture-review` to bootstrap the registry from your GDDs and ADRs." | optional — proceed without it | not expected — proceed |
| Governing ADR | path from story's ADR field | **STOP** — "ADR file [path] not found. Run `/architecture-decision` to create it, or correct the filename in the story's ADR field." | **STOP only if the story references an ADR** and its file is missing/Proposed; if it references none, proceed | no ADR required — proceed |
| Governing ADR | path from story's ADR field | **STOP** — "ADR file [path] not found. Run `/architecture-decision` to create it, or correct the filename in the story's ADR field." Also STOP if its `## Status` is `Proposed` — "ADR [path] is still Proposed. Accept it with `/architecture-decision accept [ADR-id]` before implementing." A story whose ADR field reads `N/A` (`N/A — [reason]`) references none — proceed. | **STOP only if the story references an ADR** and its file is missing/Proposed/Deprecated/Superseded; if it references none, proceed | no ADR required — proceed; **STOP only if the story references an ADR** whose file is missing/Proposed/Deprecated/Superseded |
| Control manifest | `docs/architecture/control-manifest.md` | **WARN and continue** — "Control manifest not found — layer rules cannot be checked. Run `/create-control-manifest`." | WARN and continue | skip — not expected |
At `full`, if the TR registry or governing ADR is missing, set the story status to **BLOCKED** in the session state and do not spawn any programmer agent. At `standard`/`minimal`, only a story that references an ADR whose file is **missing or `Proposed`** is set BLOCKED; a missing TR registry, or an absent-by-design ADR, does **not** block — implement against the story's acceptance criteria + the GDD/brief.
At `full`, if the TR registry is missing, or a referenced governing ADR is missing or `Proposed`, set the story status to **BLOCKED** in the session state and do not spawn any programmer agent. At `standard`/`minimal`, only a story that references an ADR whose file is **missing, `Proposed`, `Deprecated` or `Superseded`** is set BLOCKED; a missing TR registry, or an absent-by-design ADR, does **not** block — implement against the story's acceptance criteria + the GDD/brief.
Read the story file and the TR registry simultaneously — these two are
genuinely independent, unconditional reads. **The governing ADR is not part
@@ -120,22 +123,30 @@ instead of the ADR."* Re-reading the source here discards that work and, on an
ADR past the 25k `Read` cap, costs a failed read plus offset/limit retries
before implementation even starts.
**Check freshness with one line, not one file.** Resolve the ADR path from the
story, then:
**Check status and freshness with one line, not one file.** Resolve the ADR path
from the story, then:
```
Grep pattern="^## Last Verified" path="docs/architecture/[adr-file].md" output_mode="content" -A 1
Grep pattern="^## (Status|Last Verified|Date)" path="docs/architecture/[adr-file].md" output_mode="content" -A 2
```
Compare that date against the story's `**ADR Version**` field:
The `## Status` line decides first: if it reads `Proposed`, the story is BLOCKED
per the file-check table above — stop here, before any freshness comparison.
`Deprecated` or `Superseded by ADR-XXXX` blocks the same way, at every tier:
"ADR [path] is [status]; point the story at [successor] (edit its ADR field —
`/create-stories` never rewrites an existing story) before implementing."
Then resolve the ADR's **current version** the way `/create-stories` stamped it:
its `## Last Verified` date, else its `## Date`, else `unversioned`. Compare that
value against the story's `**ADR Version**` field:
| Result | Meaning | Action |
|---|---|---|
| Dates **match** | The summary was distilled from the ADR as it stands. | **Trust the story.** Do not read the ADR. |
| Versions **match** (a date on both sides) | The summary was distilled from the ADR as it stands. | **Trust the story.** Do not read the ADR. |
| Story has **no `ADR Version`** field | A story written before the stamp existed — *not* evidence of staleness. | **Trust the story**, and note in the Phase 6 summary: "Story predates the ADR Version stamp; summary trusted unverified." |
| Grep returns **no match** and the story reads `unversioned` | The ADR carries no `## Last Verified`. Consistent, not stale. | **Trust the story**; recommend `/architecture-decision [file] retrofit` to add the field. |
| Grep returns **no match** but the story names a date | Ambiguous — the ADR may have lost the field. | Treat as **mismatch** (below). |
| Dates **differ** | The ADR changed after this story was written. | **Mismatch** — resolve below. |
| Both read `unversioned` | The ADR has neither `## Last Verified` nor `## Date`. Consistent, not stale — but nothing to compare. | **Trust the story**; note "ADR carries no date; summary trusted unverified." in the Phase 6 summary, and recommend `/architecture-decision retrofit [file]`, which adds a missing `## Date`. |
| The ADR resolves to `unversioned` but the story names a date | Ambiguous — the ADR lost the field the story was stamped from. | Treat as **mismatch** (below). |
| Versions **differ** | The ADR changed after this story was written. | **Mismatch** — resolve below. |
**Never treat an absent stamp as a stale one.** A missing field means "unknown",
and the fallback for unknown is the story, not a 35k-token re-read — the two
@@ -147,15 +158,14 @@ check below:
- Prompt: "Story was written against ADR v[story-date]. The ADR is now
v[current-date]. Its decision may have changed. How do you want to proceed?"
- Options:
- `[A] Re-read the changed ADR sections and implement against current guidance (Recommended)`
- `[A] Re-read the changed ADR sections, implement against current guidance, and refresh this story's ADR summary and ADR Version (Recommended)`
- `[B] Implement from the story's summary — I accept the drift risk`
- `[C] Stop — I want to review the ADR diff first`
If **[A]**: first check the ADR's size — `Bash: wc -c "docs/architecture/[adr-file].md"`:
- **Under ~50KB** — read the whole file with one `Read` call. Measured on this
branch: at this size one read is *cheaper* than the multi-grep path (48.4k
vs 52.1k tokens on a 16KB fixture) — per-call overhead outweighs the
- **Under ~50KB** — read the whole file with one `Read` call. At this size one
read is *cheaper* than the multi-grep path — per-call overhead outweighs the
content saved. Targeted reading only pays for itself on files big enough
to threaten the 25k-token `Read` cap.
- **~50KB or larger** — read *only* the sections that govern implementation,
@@ -166,7 +176,11 @@ If **[A]**: first check the ADR's size — `Bash: wc -c "docs/architecture/[adr-
Escalate to a bounded `Read(offset, limit)` on one section only if a scanned
section cross-references material outside itself.
Then update the story's `ADR Version` to the current date so the next run is clean.
Then make the story edit that option [A] names: set its `ADR Version` to the ADR's
current version resolved above — not today's date, or the next run mismatches
again — and replace its `**ADR Decision Summary**` and `## Implementation Notes`
with the guidance you just read, so a later run that trusts the stamp is trusting
current guidance.
If **[B]**: proceed on the summary; record it in the Phase 6 "Deviations" summary.
If **[C]**: stop. Do not spawn any agent.
@@ -182,7 +196,7 @@ If they differ, use `AskUserQuestion` before proceeding:
- Prompt: "Story was written against manifest v[story-date]. Current manifest is v[current-date]. New rules may apply. How do you want to proceed?"
- Options:
- `[A] Update story manifest version and implement with current rules (Recommended)`
- `[B] Implement with old rules — I accept the risk of non-compliance`
- `[B] Implement with old rules — I accept the risk of non-compliance (the story records the current Manifest Version and a Manifest-Note)`
- `[C] Stop here — I want to review the manifest diff first`
If [A]: edit the story file's `Manifest Version:` field to the current manifest date before spawning the programmer. Then read the manifest carefully for new rules.
@@ -222,9 +236,16 @@ Read from `project.yaml` first, falling back to `.claude/docs/technical-preferen
### Mark Story In Progress
Silently update two things before spawning any agent:
Before spawning any agent, mark the story In Progress. In `collaborative` mode
ask once first — "May I mark this story In Progress? This sets `Status:` and
`Last Updated:` in `[story-path]` and its entry in `production/sprint-status.yaml`."
(leave the sprint-status file out of the question when it does not exist);
`guided` and `autonomous` update these existing files without asking
(`.claude/docs/automation-modes.md`). If the user declines, change neither file,
print `Story not marked In Progress — declined` in the Phase 6 summary, and
continue. Otherwise update two things:
1. **`production/sprint-status.yaml`** (if it exists): find the entry matching this story's file path and set `status: in_progress`. Update the top-level `updated` field to today's date. If the file does not exist, say so in one line — `Sprint status not updated: production/sprint-status.yaml absent` — and continue. Do not skip silently: `/sprint-status` reads that file to report progress, so a story that never gets marked `in_progress` is invisible to the very command a producer uses to ask what is moving.
1. **`production/sprint-status.yaml`** (if it exists): find the entry matching this story's file path and set `status: in-progress`. Update the top-level `updated` field to today's date. If the file does not exist, say so in one line — `Sprint status not updated: production/sprint-status.yaml absent` — and continue. Do not skip silently: `/sprint-status` reads that file to report progress, so a story that never gets marked `in-progress` is invisible to the very command a producer uses to ask what is moving.
2. **The story file itself**: set the story header's `Status:` field to `In Progress`, and edit its `Last Updated:` field to today's date (format: `YYYY-MM-DD`; if the field does not exist, add it after the `Status:` line). Setting `Status:` here is what actually marks the story In Progress — at `minimal` the `sprint-status.yaml` in step 1 is absent, so the story file is the only record of progress at that tier.
@@ -309,8 +330,7 @@ assumptions about post-cutoff engine APIs that need expert verification.
> `docs/engine-reference/<engine>/VERSION.md`, the VERSION.md rating wins** and an
> unknown counts as HIGH. At `minimal` there is no ADR, so VERSION.md is the only
> source; a story card carrying an improvised `MEDIUM` against a VERSION.md
> rating of HIGH would skip this spawn without saying so — which is how two wrong engine
> defaults reached a project unreviewed. `/create-stories` now derives the field
> rating of HIGH would skip this spawn without saying so. `/create-stories` now derives the field
> from the same file, so the two should agree; this check is what catches it when
> they do not.
@@ -324,7 +344,8 @@ Brief the agent with file paths and targeted reading instructions — do not ser
> **Tier note (from Phase 2):** items 2–4 below assume the `full` baseline. At
> `standard`, include the TR registry only if it exists and the governing ADR
> only where the story references one. At `minimal`, the TR registry, ADR, and
> only where the story references one — at any tier, a story whose ADR field
> reads `N/A` has no item 3. At `minimal`, the TR registry, ADR, and
> control manifest are typically absent — **omit items 2–4 and brief the agent to
> implement against the story's Acceptance Criteria and the GDD/brief** (the
> story file from item 1). Never instruct the agent to read a file Phase 2
@@ -339,8 +360,8 @@ Brief the agent with file paths and targeted reading instructions — do not ser
> Implement against the story's Acceptance Criteria and the GDD/brief. Do not
> go looking for it."* Same form for an absent ADR or control manifest.
> - **To the user**, one line before spawning: `Briefing omits: TR registry
> (absent), control manifest (absent) — implementing against acceptance
> criteria + GDD.`
> (absent), ADR guidance (story references no ADR), control manifest
> (absent) — implementing against acceptance criteria + GDD.`
>
> Without this, a `standard` run where the registry legitimately does not exist
> and one where `/architecture-review` was supposed to bootstrap it and nobody
@@ -348,11 +369,11 @@ Brief the agent with file paths and targeted reading instructions — do not ser
1. **Story file**: `[story-path]` — the agent reads this one file; it carries the acceptance criteria, Out of Scope boundaries, and QA test cases
2. **GDD requirement**: look up TR-ID `[TR-XXX-NNN]` in `docs/architecture/tr-registry.yaml` — use the `requirement` field as source of truth
3. **ADR guidance**: pass the story's `**ADR Decision Summary**` and `## Implementation Notes` **inline in the prompt** — do not pass the ADR path. Phase 2 already established that this summary is current; handing the agent a path makes it re-read the whole ADR in its own context, paying the cost this skill just avoided. Pass the path *only* if Phase 2 hit the mismatch branch and the user chose `[C]`-style deferral, in which case say which sections to grep.
3. **ADR guidance**: pass the story's `**ADR Decision Summary**` and `## Implementation Notes` **inline in the prompt** — do not pass the ADR path. Phase 2 already established that this summary is current; handing the agent a path makes it re-read the whole ADR in its own context, paying the cost this skill just avoided. After mismatch option `[A]`, pass the guidance freshly read from the ADR's `## Decision` (the text [A] just wrote into the story), never the stale summary the story carried before; after `[B]`, pass the story's summary and tell the agent it predates the current ADR.
4. **Control manifest**: `docs/architecture/control-manifest.md` — read rules for the **[layer]** layer only
5. **Engine preferences**: `naming.*` and `performance.*` from `project.yaml` (for any key absent or empty, fall back to `.claude/docs/technical-preferences.md`)
6. **Test file path**: `[path from story's Test Evidence section]` — this file must be created as part of implementation
7. **Test requirement** (Logic and Integration stories only; **omit this entire item at `qa.level: minimal`** — tests are not required there. When you omit it, tell the agent so explicitly: *"Do not write a test file for this story — test evidence is waived at `qa.level: minimal`."* An omitted item and a forgotten one are indistinguishable to the agent, and a programmer briefed with no test instruction may write tests anyway, or may silently assume they were meant to): The test file MUST be created at `[path from the story's Test Evidence section]`. Write the test alongside the implementation — do not defer it. At `qa.level: standard`/`full` the story cannot be closed via `/story-done` without this file present. Each acceptance criterion must have at least one test function covering it. Test file naming: `[system]_[feature]_test.[ext]`. Function naming: `test_[scenario]_[expected_outcome]`. No random seeds, no time-dependent assertions, no external I/O.
7. **Test requirement** (Logic and Integration stories only; **omit this entire item at `qa.level: minimal`** — tests are not required there. When you omit it for a Logic or Integration story, tell the agent so explicitly — never a UI, Visual/Feel or Config/Data story, which this item never covered: *"Do not write a test file for this story — test evidence is waived at `qa.level: minimal`."* An omitted item and a forgotten one are indistinguishable to the agent, and a programmer briefed with no test instruction may write tests anyway, or may silently assume they were meant to): The test file MUST be created at `[path from the story's Test Evidence section]`. Write the test alongside the implementation — do not defer it. At `qa.level: standard`/`full` the story cannot be closed via `/story-done` without this file present. Each acceptance criterion must have at least one test function covering it. Test naming per engine, from `.claude/rules/test-standards.md`: Godot `test_[scenario]_[expected]` in `[system]_[feature]_test.gd`; Unity `[Scenario]_[Expected]` in a `[System]Tests` class; Unreal `<Project>.[System].[Scenario]`. No random seeds, no time-dependent assertions, no external I/O.
8. **Explicit instruction**: implement this story following the ADR guidelines, respect the manifest rules, stay within the story's Out of Scope boundaries. Write clean, doc-commented public APIs.
The agent should:
@@ -364,9 +385,9 @@ The agent should:
### Config/Data stories (no agent needed)
For Type: Config/Data stories, no programmer agent is required. The implementation
is editing a data file. Read the story's acceptance criteria and make the specified
changes to the data file directly. Note which values were changed and what they
changed from/to.
is editing a data file. Read the story's acceptance criteria, show the specified
changes as from → to values, and ask "May I write to [data file path]?" before
editing it directly. Note which values were changed and what they changed from/to.
### Visual/Feel stories
@@ -385,11 +406,13 @@ The test requirement was included in the Phase 4 programmer agent brief (item 7)
**Skip this phase at `qa.level: minimal`** (resolved earlier) — no test evidence
is required, so there is nothing to gate; do not flag the story unverifiable for a
missing test.
missing test. **The Visual/Feel and UI screenshot line at the end of this phase
still applies** — `qa.level` waives tests, never the look.
> **Say so in the Phase 6 summary.** A skipped phase must announce itself in the
> output, not only in this file (`.claude/rules/skill-authoring.md`, obligation
> 3). Emit the line:
> 3). For a Logic or Integration story — the types Phase 4 item 7 briefs a test
> for — emit the line:
>
> > *Test evidence: **waived** at `qa.level: minimal` — no test was required or
> > written for this story.*
@@ -443,7 +466,7 @@ product, and an advisory visual gate gets deferred in favour of whatever does
block. A project that genuinely does not need it sets `testing.strict.visual` or
`testing.strict.ui` to `false`.
For Visual/Feel and UI stories, include in the Phase 6 summary: "Retained screenshot required at `production/qa/evidence/[slug]-evidence.md` before this story can be closed — at the default BLOCKING level a story with no screenshot on disk is unverifiable."
For Visual/Feel and UI stories, include in the Phase 6 summary: "Retained screenshot required under `production/qa/evidence/[story-slug]/` before this story can be closed — at the default BLOCKING level a story with no screenshot on disk is unverifiable." For Visual/Feel, add that the sign-off in `production/qa/evidence/[slug]-evidence.md` is also required.
---
@@ -461,10 +484,28 @@ Before collecting anything:
1. **Check the agent's own terminal state.** If it reported stopping early, hit a
turn/step limit, or its report ends mid-task, treat the story as **INCOMPLETE**.
2. **Verify the output parses.** Run the cheapest check the engine offers —
`commands.test` or `commands.smoke` from `project.yaml`, or for Godot
`godot --headless --path . --import`, which surfaces parse errors without
running the game. Report what you ran and what it said.
2. **Verify the output parses.** Run the check whose **exit code** answers the
question — an exit 0 from a command that does not check is how broken code
gets reported as clean:
- **Godot:** `godot --headless --path . --import` once (it builds the class
cache), then one run over every `.gd` the story added or changed:
`godot --headless --path . -s res://.claude/scripts/godot-parse-check.gd -- res://<file>.gd …`.
For `godot`, use the executable `commands.test` names, else the editor
`engine.path` records, else `godot` on `PATH`; if none resolves, write
`parse NOT VERIFIED — Godot executable not found`.
Exit 1 means a script did not load — its `PARSE FAIL:` line names it, with
Godot's error above. Do not use `--check-only`: it fails valid code that
names an autoload. `--import` and `--quit-after` on their own exit 0 on a
parse error — they are not parse checks.
- **Unity:** `commands.smoke` (`-batchmode -quit -projectPath . -logFile -`)
— exit 1 with `error CS…` lines when a script does not compile.
- **Unreal:** build the editor target —
`"<UE root>/Engine/Binaries/DotNET/UnrealBuildTool/UnrealBuildTool.exe" <Project>Editor Win64 Development -Project="<absolute path>/<Project>.uproject"`
on Windows; on Linux `"<UE root>/Engine/Build/BatchFiles/Linux/Build.sh" <Project>Editor Linux Development -Project=…`,
on macOS `…/Mac/Build.sh <Project>Editor Mac Development -Project=…` (from Epic's
documentation — `docs/engine-reference/unreal/current-best-practices.md`, "Command Line").
A compile error fails the build (`Result: Failed`, non-zero exit).
Report what you ran, its exit code, and any error lines.
3. If the engine binary is unavailable, write **`parse NOT VERIFIED — engine
binary not available`**. Do not infer that the code is fine because it reads
correctly; that inference is exactly what this step exists to replace.
@@ -477,6 +518,11 @@ Before collecting anything:
an overflowing panel, a missing element are defects, and this is the only
step that finds them. Procedure per engine, including how to capture
unattended in Godot, Unity and Unreal: `.claude/docs/run-and-observe.md`.
**On Unity** the capture needs the `ScreenshotOnArg.cs` script that file gives
verbatim. If the project has none (Glob `Assets/**/ScreenshotOnArg.cs`), ask
"May I write `Assets/Scripts/ScreenshotOnArg.cs`?" and write it exactly as
given there before launching; if the user declines, nothing can capture —
report `Run result: NOT VERIFIED — ScreenshotOnArg.cs not written`.
Report exactly one line — `Run result: OBSERVED — <what was on screen>`
with the retained path, `Run result: NOT VERIFIED — <reason>`, or
`Run result: N/A — <reason>` for a story with genuinely nothing observable.
@@ -506,7 +552,7 @@ Present a concise implementation summary:
**Files changed**:
- `<code root>/[path]` — created / modified ([brief description])
- `tests/[path]` — test file ([N] test functions) — *omit this line at
`qa.level: minimal` and print the Phase 5 waiver line instead*
`qa.level: minimal` and print the Phase 5 waiver line instead (Logic/Integration)*
**Verification**: [what was run] — [result, or `NOT VERIFIED — <reason>`]
**Run result**: [`OBSERVED — <what was on screen>` + retained path | `NOT VERIFIED — <reason>` | `N/A — <reason>`] — see `.claude/docs/run-and-observe.md`
@@ -521,27 +567,46 @@ Present a concise implementation summary:
**Engine risks flagged**: [None] or [specialist finding]
**Blockers**: [None] or [describe]
**Before running `/story-done`:** run your test suite locally and confirm the tests you wrote pass. *(At `qa.level: minimal` no tests were written — print the Phase 5 waiver line here instead of this paragraph. Telling a user to confirm the passing of tests that do not exist is worse than saying nothing.)* **`/story-done` does NOT re-run them** — its Phase 3 checks that the test FILE exists, with `Glob`, and nothing executes it. A test that exists and fails satisfies that gate. Nothing downstream makes the local run safe to skip. Pass/fail is established by `/gate-check` and `/smoke-check`, both of which execute a suite — and both come later than story closure.
**Before running `/story-done`:** run your test suite locally and confirm the tests you wrote pass. *(At `qa.level: minimal` no tests were written — print the Phase 5 waiver line here instead of this paragraph for a Logic or Integration story, and omit both for any other type. Telling a user to confirm the passing of tests that do not exist is worse than saying nothing.)* **`/story-done` does NOT re-run them** — its Phase 3 checks that the test FILE exists, with `Glob`, and nothing executes it. A test that exists and fails satisfies that gate. Nothing downstream makes the local run safe to skip. Pass/fail is established by `/gate-check` and `/smoke-check`, both of which execute a suite — and both come later than story closure.
Ready for: `/code-review [file1] [file2]` then `/story-done [story-path]`
Ready for: `/story-done [story-path]` — at `standard`/`full`, `/code-review [file1] [file2]` first
```
---
## Phase 7: Update Session State
Silently append to `production/session-state/active.md`:
Silently update the checkpoint in `production/session-state/active.md` —
**overwrite the `<!-- CHECKPOINT -->` … `<!-- /CHECKPOINT -->` block, never
append** (schema: `.claude/docs/templates/session-state.md`). `session-start.sh`
shows exactly that block when the next session opens, so it is what a cold
resume starts from:
```
## Session Extract — /dev-story [date]
- Story: [story-path] — [story title]
- Files changed: [comma-separated list]
- Test written: [path, or "None — Visual/Feel/Config story"]
- Blockers: [None, or description]
- Next: /code-review [files] then /story-done [story-path]
<!-- CHECKPOINT -->
**Updated:** [date]
**Branch:** `[current git branch]`
**Current task:** /dev-story — [story-path] ([story title])
**Next step:** /story-done [story-path] (at standard/full: /code-review [files] first)
**Blocked on:** [nothing, or the blocker]
**Files in progress:** [files changed, comma-separated; test file included]
**Run result:** [the Phase 6 `Run result:` line, verbatim — `/story-done` reads it here]
**Open questions:** [none, or one line each]
<!-- /CHECKPOINT -->
```
Create `active.md` if it does not exist. Confirm: "Session state updated."
**Next step** follows the Phase 6 result — the line above is the Implementation
Complete one. On **INCOMPLETE** write
`**Next step:** /dev-story [story-path] — resume: [the breakage Phase 6 named]`.
On **BLOCKED** (Phase 2) write the unblocking action instead —
`/architecture-decision accept ADR-NNNN`, the dependency story to finish, the
manifest diff to review — and fill **Blocked on**. `/help` reads this line: a
checkpoint that says `/story-done` tells it the work is written.
If `active.md` does not exist, create it from the template. If it exists with no
markers (a file from before the schema), insert the template's STATUS and
CHECKPOINT blocks at the top and leave the rest untouched. Confirm: "Session
state updated."
---
@@ -561,7 +626,7 @@ partial report.** Full procedure: `.claude/docs/error-recovery-protocol.md`.
Common blockers:
- Input file missing (story not found, GDD absent) → redirect to the skill that creates it
- A *referenced* ADR's status is Proposed → do not implement; run `/architecture-decision` first (at `standard`/`minimal` a story that references no ADR is not blocked on this — see Phase 2)
- A *referenced* ADR's status is Proposed → do not implement; accept it with `/architecture-decision accept ADR-NNNN` once decided (a story that references no ADR is not blocked on this — see Phase 2)
- Scope too large → split into two stories via `/create-stories`
- Conflicting instructions between ADR and story → surface the conflict, do not guess
- Manifest version mismatch → show diff to user, ask whether to proceed with old rules or update story first
@@ -572,7 +637,14 @@ Common blockers:
`autonomous` modes, see `.claude/docs/automation-modes.md` — the rules below
describe what collaborative mode requires, not universal behavior.
- **File writes are delegated** — all source code, test files, and evidence docs are written by sub-agents spawned via `Agent`. Each sub-agent enforces the "May I write to [path]?" protocol individually. This orchestrator does not write files directly.
- **File writes are delegated** — all source code, test files, and evidence docs are written by sub-agents spawned via `Agent`. Each sub-agent enforces the "May I write to [path]?" protocol individually. This orchestrator writes only the following, each after an ask that names it:
- the story's `Status:` / `Last Updated:` and its `production/sprint-status.yaml` entry — the one "May I mark this story In Progress?" ask (Phase 2)
- the story's `ADR Version`, `**ADR Decision Summary**` and `## Implementation Notes` (ADR mismatch option [A]), and its `Manifest Version:` / `Manifest-Note:` (manifest option [A] or [B]) — each option names that edit, so choosing it is the ask
- a dependency story's `Status: Complete` (dependency option [C], then "May I update [dependency path] Status to Complete?")
- a Config/Data story's data file ("May I write to [path]?")
- on Unity, `Assets/Scripts/ScreenshotOnArg.cs`, written verbatim from `.claude/docs/run-and-observe.md` ("May I write `Assets/Scripts/ScreenshotOnArg.cs`?", Phase 6)
The session-state checkpoint in `production/session-state/active.md` is the one write made without an ask.
- **Load before implementing** — do not start coding until all context is loaded
(story, TR-ID, ADR, manifest, engine prefs). Incomplete context produces code
that drifts from design.
@@ -586,8 +658,11 @@ describe what collaborative mode requires, not universal behavior.
- **Test is not optional for Logic/Integration** (at `qa.level: standard`/`full`) —
do not mark implementation complete without the test file existing. At
`qa.level: minimal` tests are not required and this does not apply.
- **Visual/Feel criteria are deferred, not skipped** — mark them as DEFERRED
in the summary; they will be manually verified in `/story-done`
- **Visual/Feel and UI looks are observed, not deferred** — the Phase 6 run
retains the screenshot (each screen touched for UI; Visual/Feel also needs a
lead sign-off before `/story-done`), and `qa.level` never waives either. Only
the *feel* half of a Visual/Feel criterion — timing, weight, responsiveness —
is marked DEFERRED, for `/team-qa`
- **Ask before large structural decisions** — if the story requires an
architectural pattern not covered by the ADR, surface it before implementing:
"The ADR doesn't specify how to handle [case]. My plan is [X]. Proceed?"
@@ -596,6 +671,6 @@ describe what collaborative mode requires, not universal behavior.
## Recommended Next Steps
- Run `/code-review [file1] [file2]` to review the implementation before closing the story
- At `standard`/`full`, run `/code-review [file1] [file2]` to review the implementation before closing the story (not part of the minimal loop)
- Run `/story-done [story-path]` to verify acceptance criteria and mark the story complete
- After all sprint stories are done: run `/team-qa sprint` for the full QA cycle before advancing the project stage
- With a sprint plan, after all sprint stories are done: run `/team-qa sprint` for the full QA cycle before advancing the project stage. At `minimal`, `/story-done` names the next story instead