mirror of
https://github.com/Donchitos/Claude-Code-Game-Studios.git
synced 2026-10-16 01:37:05 +00:00
Release 1.1.0 — one config file, and a process weight you choose
`project.yaml` at the repo root is now the single source of truth for a project's configuration, replacing `production/stage.txt`, `production/review-mode.txt` and `.claude/docs/technical-preferences.md` (all three still read as a fallback; nothing is force-deleted). **`modes.rigor` — one question instead of six.** `minimal`, `standard` or `full` fronts six knobs: `modes.workflow`, `docs.density`, `qa.level`, `modes.story_granularity`, `modes.review_mode` and `team.size`. It defaults to `minimal`, which is a change from 1.0's behaviour: the heavier tier was measured costing several times more to reach working code without producing a better result, and returning nothing when a fresh developer inherited the project. Pin `modes.rigor: standard` to keep 1.0's process level. Also in this release: - `/settings` to view or change any setting, and `project.local.yaml` for per-developer preferences that should not be committed. - `system_overrides` to hold one system to a higher standard than the rest of the project, and `testing.strict` to set per test type whether missing evidence blocks a story or warns. - A story that changes anything the player sees is not closed until the game has been launched, observed, and a screenshot retained in `production/qa/evidence/`. A parse check is not a run. This holds at every rigor level, including `minimal`, where automated tests are waived but the look is not. - The code root is engine-specific and enforced as such: Godot `src/`, Unity `Assets/`, Unreal `Source/<Module>/`. Two of the three will not build a project laid out any other way. - Migration tooling for existing projects: `.claude/scripts/migrate-v1-config.sh` converts a 1.0 layout, non-destructively by default, with a report to review before `--finalize` deletes anything. - Ask-before-write holds regardless of personal automation settings. Upgrading from 1.0 or earlier: see UPGRADING.md. Full list of changes: CHANGELOG.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016xvzG3i7pWQg4LjyDwWMXd
This commit is contained in:
co-authored by
Claude Opus 5
parent
984023ddac
commit
d05699707f
@@ -0,0 +1,78 @@
|
||||
# /dev-story — Handoff Contract
|
||||
|
||||
## Role in Pipeline
|
||||
Bridges planning and code by loading the full context for a single story (story file, TR registry, ADR, control manifest, engine prefs), routing to the correct programmer agent, implementing source code and tests, and leaving the story ready for `/code-review` then `/story-done`.
|
||||
|
||||
## Inputs Required
|
||||
|
||||
### Files That Must Exist
|
||||
| File | Required Fields / Sections | Read-Only? |
|
||||
|------|---------------------------|-----------|
|
||||
| `production/epics/**/*.md` (the story file) | `Status: Ready`, `TR-ID`, `Governing ADR`, `Manifest Version`, `## Acceptance Criteria`, `## Test Evidence`, `## Dependencies`, `## Out of Scope` | **Partially mutable.** This skill sets `Status:` to `In Progress` and updates `Last Updated:` before spawning any agent (Phase 2) — at `minimal` the story file is the only record of progress, since `sprint-status.yaml` is absent. Everything else in the story file is read-only to this skill |
|
||||
| `docs/architecture/tr-registry.yaml` | Entry matching the story's TR-ID with current `requirement` text | Yes |
|
||||
| `docs/architecture/adr-NNNN-[slug].md` (referenced ADR) | `## Decision`, `## Implementation Guidelines`, `## Engine Compatibility`, `## ADR Dependencies` | Yes |
|
||||
| `docs/architecture/control-manifest.md` | `Manifest Version:` header, layer rules (required patterns, forbidden patterns, performance guardrails) | Yes |
|
||||
| `project.yaml` | `engine.name`, `engine.version`, `naming.*`, `performance.*` — the primary source for each of these fields | Yes |
|
||||
| `.claude/docs/technical-preferences.md` | Legacy fallback for any field above that is absent or empty in `project.yaml`; **sole** source for forbidden patterns and allowed libraries (deliberately never migrated), plus the `Engine Specialists` section | Yes — required only for fields absent from `project.yaml`, and always for forbidden patterns |
|
||||
| `docs/engine-reference/[engine]/VERSION.md` | Engine version, LLM knowledge cutoff, post-cutoff risk levels | Yes |
|
||||
| `production/session-state/active.md` | (read to find active story when no argument given; created if absent) | No |
|
||||
|
||||
### Preconditions
|
||||
- The target story must have `Status: Ready` (validated by `/story-readiness` before invocation)
|
||||
- The ADR referenced in the story must have `Status: Accepted` — if `Status: Proposed`, do not implement; surface this as a blocker and direct user to `/architecture-decision`
|
||||
- All `## Dependencies` stories listed in the story file must already have `Status: Complete` (or `Status: Done`)
|
||||
- An engine must be configured — `engine.name` in `project.yaml`, or as legacy fallback an `**Engine**:` value in `.claude/docs/technical-preferences.md` that is not `[TO BE CONFIGURED]`
|
||||
- `docs/architecture/tr-registry.yaml` must contain the story's TR-ID
|
||||
- `docs/architecture/control-manifest.md` must exist (required for layer rule enforcement)
|
||||
|
||||
## Outputs Produced
|
||||
|
||||
### Files Written
|
||||
| File | Guaranteed Fields / Sections | Notes |
|
||||
|------|------------------------------|-------|
|
||||
| `<code root>/[system]/[file].[ext]` | Doc-commented public APIs; no hardcoded gameplay values; follows ADR Implementation Guidelines and control-manifest required patterns | created or modified by sub-agent; code root resolved per `.claude/docs/code-root-resolution.md` |
|
||||
| `tests/unit/[system]/[story-slug]_test.[ext]` OR `tests/integration/[system]/[story-slug]_test.[ext]` | One test function per acceptance criterion (Logic/Integration stories only); naming: `test_[scenario]_[expected_outcome]`; no random seeds; no external I/O | created by sub-agent; path matches `## Test Evidence` in story |
|
||||
| `production/session-state/active.md` | `## Session Extract — /dev-story [date]` block: story path, files changed, test written path, blockers, next steps | appended (created if absent) |
|
||||
|
||||
### Output Guarantees
|
||||
- All source files follow the naming conventions in `project.yaml` (`naming.*`), falling back to `.claude/docs/technical-preferences.md` for any convention absent there
|
||||
- Test file path matches exactly the path declared in the story's `## Test Evidence` section
|
||||
- Every acceptance criterion is mapped to a test function (Logic/Integration), an `OBSERVED` retained screenshot (the *look* half of Visual/Feel and UI), or flagged `DEFERRED` (the *feel* half only — timing, weight, responsiveness) in the implementation summary
|
||||
- No files are written outside the story's `## Out of Scope` boundary without surfacing the conflict to the user first
|
||||
- Session state records files changed and the next recommended invocations (`/code-review` then `/story-done`)
|
||||
- The implementation summary states a **verification** result — what was run against the written code (`commands.test`, `commands.smoke`, or the engine's headless import) and its outcome. When the engine binary is unavailable this is **`NOT VERIFIED — <reason>`**, never an inference that the code is fine because it reads correctly
|
||||
- The implementation summary states a **run result** — `OBSERVED — <what was on screen>` with a retained screenshot under `production/qa/evidence/[story-slug]/`, `NOT VERIFIED — <reason>`, or `N/A — <reason>` (only for a story with genuinely nothing observable). `NOT VERIFIED` is a blocker at the default gate level for Visual/Feel and UI stories. The run is **not waived at `qa.level: minimal`** — tests are, the look is not. Procedure: `.claude/docs/run-and-observe.md`
|
||||
- At `qa.level: minimal` no test file is written, and the summary says so explicitly (`Test evidence: waived at qa.level: minimal`). A waived run and a run where tests were forgotten must not produce the same artifact
|
||||
- **`NOT ASSESSED` is an accepted inbound value of the story's `Risk` field** (`/create-stories` emits it when `VERSION.md` assigns no level). This skill treats it as HIGH for the engine-specialist spawn decision
|
||||
- **Completion is not assumed.** If the programmer agent stopped early or its output fails to parse, the story is reported **INCOMPLETE** with the specific breakage named, and `Implementation Complete` is not emitted
|
||||
|
||||
## Immutability Rules
|
||||
- READS but does NOT modify: `project.yaml`, `docs/architecture/tr-registry.yaml`, `docs/architecture/adr-NNNN-[slug].md`, all GDD files in `design/gdd/`, `docs/architecture/control-manifest.md`, `.claude/docs/technical-preferences.md` (legacy fallback), `docs/engine-reference/[engine]/VERSION.md`
|
||||
- MODIFIES: `<code root>/**` (new/updated source files, via sub-agent; code root resolved per `.claude/docs/code-root-resolution.md`), `tests/**` (new test file, via sub-agent), `production/session-state/active.md` (append only)
|
||||
- Updates the story file's `Status` field to `In Progress` only (Phase 2, before
|
||||
spawning any agent). It writes no other `Status` value: advancing a story to
|
||||
`Complete` is the exclusive responsibility of `/story-done`
|
||||
|
||||
## Hard Constraints (Never Violate)
|
||||
- Never marks a story `Status: Done` or `Status: Complete` — that belongs to `/story-done`
|
||||
- Never begins implementation without loading the full context package (story, TR-ID from registry, ADR Decision + Implementation Guidelines, control-manifest layer rules, engine prefs)
|
||||
- Never implements a story whose referenced ADR has `Status: Proposed` — surface as a blocker
|
||||
- Never writes a Logic or Integration story as complete without a test file at the path declared in `## Test Evidence`
|
||||
- Never touches files listed in the story's `## Out of Scope` section without explicit user approval
|
||||
- Never deviates from the ADR's Implementation Guidelines silently — deviations must be flagged in the summary
|
||||
- Never modifies ADR files or GDD files under any circumstances
|
||||
- All file writes are delegated to sub-agents via Task; this orchestrator does not write source or test files directly
|
||||
|
||||
## Downstream Skill Expects
|
||||
**Next skill:** `/story-done`
|
||||
- It will read: the story file (to check `Status`, `## Acceptance Criteria`, `## Test Evidence` path, `Type:`, referenced ADR, TR-ID)
|
||||
- It assumes: the test file declared in `## Test Evidence` already exists on disk (for Logic/Integration stories)
|
||||
- It assumes: `production/session-state/active.md` records the story path and files changed (used to locate the in-progress story when no argument is given)
|
||||
- It assumes: source files under the resolved code root are present and match the criterion descriptions, so Grep-based deviation checks can run
|
||||
|
||||
## Known Fragile Points
|
||||
- If the story's embedded `Manifest Version` differs from the current `docs/architecture/control-manifest.md` header date, rules may have changed since the story was authored — the skill surfaces this, but silently proceeding would produce code that violates newer manifest rules
|
||||
- The test file path in `## Test Evidence` must be exact: `/story-done` uses that literal path for Glob checks; a typo here causes a false BLOCKING result downstream
|
||||
- If `docs/architecture/tr-registry.yaml` has a stale `requirement` text that diverges from the GDD, the implementation may satisfy the registry but fail the GDD — always treat the registry as authoritative per design, but flag if a visible discrepancy is noticed
|
||||
- Sub-agent task failures are non-fatal by design (partial reports are surfaced), but a blocked programmer sub-agent means no source files are written — `/story-done` will then fail its file-existence checks
|
||||
- Config/Data stories produce no test file; `/story-done` must see `Type: Config/Data` in the story header to classify the story correctly — otherwise it resolves the test-evidence gate for the wrong type (e.g. Logic, which is BLOCKING by default) and may flag a missing test
|
||||
@@ -1,12 +1,19 @@
|
||||
---
|
||||
name: dev-story
|
||||
description: "Read a story file and implement it. Loads the full context (story, GDD requirement, ADR guidelines, control manifest), routes to the right programmer agent for the system and engine, implements the code and test, and confirms each acceptance criterion. The core implementation skill — run after /story-readiness, before /code-review and /story-done."
|
||||
description: "Implement a story: ADR guidelines, right programmer agent, code plus test. After /story-readiness, before /code-review and /story-done."
|
||||
argument-hint: "[story-path]"
|
||||
user-invocable: true
|
||||
allowed-tools: Read, Glob, Grep, Write, Bash, Task, AskUserQuestion
|
||||
disable-model-invocation: true
|
||||
allowed-tools: Read, Glob, Grep, Write, Edit, Bash, Agent, AskUserQuestion
|
||||
model: sonnet
|
||||
---
|
||||
|
||||
!`source "${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/yaml-helper.sh" 2>/dev/null && resolve_config --keys automation,workflow,story_granularity,qa.level,testing.strict,system_overrides`
|
||||
|
||||
Resolved above — use as-is. No block → defaults in
|
||||
`.claude/docs/config-resolution.md`.
|
||||
|
||||
|
||||
# Dev Story
|
||||
|
||||
This skill bridges planning and code. It reads a story file in full, assembles
|
||||
@@ -24,10 +31,33 @@ drives implementation to completion — including writing the test.
|
||||
|
||||
**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 + test file in the project's `src/` and `tests/` directories.
|
||||
**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`.
|
||||
|
||||
---
|
||||
|
||||
Every `AskUserQuestion` call follows `.claude/docs/automation-modes.md`
|
||||
(collaborative asks always · guided major-only · autonomous logs and proceeds;
|
||||
`automation_always_ask` categories always prompt).
|
||||
|
||||
**Workflow tier**: resolved per the story's system (per
|
||||
`.claude/docs/workflow-modes.md`) — **the GDD filename stem** of the story's
|
||||
`GDD:` path (`design/gdd/<stem>.md` → `<stem>`), with the `[system]` segment of
|
||||
its `TR-[system]-NNN` ID accepted only as a fallback alias: use the
|
||||
`system_overrides` row for that system if the block lists one, else the
|
||||
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**
|
||||
at `fine` (tighter context). It does not change the prerequisite gate.
|
||||
|
||||
**`qa.level`**: controls whether the programmer brief carries
|
||||
a test requirement. At `minimal`, omit the "Test requirement" line (Phase 4 item 7)
|
||||
— tests are not required; at `standard`, include the per-type test requirement; at
|
||||
`full`, also pass a coverage target. Distinct from `workflow: minimal`. When tests
|
||||
are not required (`minimal`), the Phase 5 `testing.strict` gate is a no-op.
|
||||
|
||||
## Phase 1: Find the Story
|
||||
|
||||
**If a path is provided**: read that file directly.
|
||||
@@ -41,23 +71,32 @@ If not found, ask: "Which story are we implementing?" Glob
|
||||
|
||||
## Phase 2: Load Full Context
|
||||
|
||||
**Before loading any context, verify required files exist.** Extract the ADR path from the story's `ADR Governing Implementation` field, then check:
|
||||
**Before loading any context, resolve the workflow tier for this story's system** (see the Workflow tier note above), then **verify required files exist.** Extract the ADR path from the story's `ADR Governing Implementation` field. The "If missing — `full`" column is the baseline; the tier columns relax it:
|
||||
|
||||
| File | Path | If missing |
|
||||
|------|------|------------|
|
||||
| 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." |
|
||||
| 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." |
|
||||
| Control manifest | `docs/architecture/control-manifest.md` | **WARN and continue** — "Control manifest not found — layer rules cannot be checked. Run `/create-control-manifest`." |
|
||||
| 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 |
|
||||
| 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 |
|
||||
|
||||
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 `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.
|
||||
|
||||
Read all of the following simultaneously — these are independent reads. Do not start implementation until all context is loaded:
|
||||
Read the story file and the TR registry simultaneously — these two are
|
||||
genuinely independent, unconditional reads. **The governing ADR is not part
|
||||
of this batch — do not include it in the same parallel tool-call group as
|
||||
these two.** Its own section below is a gate, not a read: whether the ADR
|
||||
gets opened at all depends on a freshness check that itself depends on the
|
||||
story file already being read. Do not start implementation until this phase
|
||||
is fully resolved:
|
||||
|
||||
### The story file
|
||||
Extract and hold:
|
||||
- **Story title, ID, layer, type** (Logic / Integration / Visual/Feel / UI / Config/Data)
|
||||
- **TR-ID** — the GDD requirement identifier
|
||||
- **Governing ADR** reference
|
||||
- **ADR Version** stamp embedded in story header (absent on pre-stamp stories)
|
||||
- **ADR Decision Summary** and **Implementation Notes** — the distilled ADR
|
||||
guidance; this is the primary source for what the ADR decided
|
||||
- **Manifest Version** embedded in story header
|
||||
- **Acceptance Criteria** — every checkbox item, verbatim
|
||||
- **Implementation Notes** — the ADR guidance section in the story
|
||||
@@ -66,19 +105,74 @@ Extract and hold:
|
||||
- **Dependencies** — what must be DONE before this story
|
||||
|
||||
### The TR registry
|
||||
Read `docs/architecture/tr-registry.yaml`. Look up the story's TR-ID.
|
||||
Read the current `requirement` text — this is the source of truth for what the
|
||||
GDD requires now. Do not rely on any inline text in the story file (may be stale).
|
||||
Grep the story's TR-ID from `docs/architecture/tr-registry.yaml`
|
||||
(`Grep pattern="id: <TR-ID>" path="docs/architecture/tr-registry.yaml" output_mode="content" -A 6`)
|
||||
rather than reading the whole cross-system registry. Read the matched entry's current
|
||||
`requirement` text — this is the source of truth for what the GDD requires now. Do not
|
||||
rely on any inline text in the story file (may be stale).
|
||||
|
||||
### The governing ADR
|
||||
Read `docs/architecture/[adr-file].md`. Extract:
|
||||
- The full Decision section
|
||||
- The Implementation Guidelines section (this is what the programmer follows)
|
||||
- The Engine Compatibility section (post-cutoff APIs, known risks)
|
||||
- The ADR Dependencies section
|
||||
|
||||
**Do not open the ADR by default.** `/create-stories` already distilled it into
|
||||
this story's `**ADR Decision Summary**` + `## Implementation Notes`, and its
|
||||
template states the contract outright: *"This is what the programmer reads
|
||||
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:
|
||||
|
||||
```
|
||||
Grep pattern="^## Last Verified" path="docs/architecture/[adr-file].md" output_mode="content" -A 1
|
||||
```
|
||||
|
||||
Compare that date 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. |
|
||||
| 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. |
|
||||
|
||||
**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
|
||||
staleness gates that already exist (`/story-readiness` on Manifest Version,
|
||||
`/code-review` post-implementation) are what make that safe.
|
||||
|
||||
**On mismatch**, use `AskUserQuestion` — same shape as the Manifest Version
|
||||
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)`
|
||||
- `[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
|
||||
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,
|
||||
never the whole file:
|
||||
```
|
||||
Grep pattern="^## (Decision|Engine Compatibility|ADR Dependencies)" path="docs/architecture/[adr-file].md" output_mode="content" -A 40
|
||||
```
|
||||
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.
|
||||
If **[B]**: proceed on the summary; record it in the Phase 6 "Deviations" summary.
|
||||
If **[C]**: stop. Do not spawn any agent.
|
||||
|
||||
### The control manifest
|
||||
Read `docs/architecture/control-manifest.md`. Extract the rules for this story's layer:
|
||||
Read only this story's layer from `docs/architecture/control-manifest.md` — grep that one
|
||||
section (`Grep pattern="^## <layer> Layer Rules" path="docs/architecture/control-manifest.md" output_mode="content" -A 40`) rather than a full read of every layer. Extract the rules for this story's layer:
|
||||
- Required patterns
|
||||
- Forbidden patterns
|
||||
- Performance guardrails
|
||||
@@ -117,26 +211,29 @@ If a dependency file cannot be found: warn "Dependency story not found: [path].
|
||||
---
|
||||
|
||||
### Engine reference
|
||||
Read `.claude/docs/technical-preferences.md`:
|
||||
- `Engine:` value — determines which programmer agents to use
|
||||
- Naming conventions (class names, file names, signal/event names)
|
||||
- Performance budgets (frame budget, memory ceiling)
|
||||
- Forbidden patterns
|
||||
Read from `project.yaml` first, falling back to `.claude/docs/technical-preferences.md` for any key absent or empty:
|
||||
- `specialists.*` — the project's chosen specialist agents; **read before**
|
||||
`engine.name` when selecting an agent (see Phase 3)
|
||||
- `engine.name` (else the `Engine:` value) — the generic engine specialist, and
|
||||
the fallback when `specialists` is absent
|
||||
- `naming.*` (else Naming conventions) — class names, file names, signal/event names
|
||||
- `performance.*` (else Performance budgets) — frame budget, memory ceiling
|
||||
- Forbidden patterns — from `.claude/docs/technical-preferences.md` (not migrated to project.yaml)
|
||||
|
||||
### Mark Story In Progress
|
||||
|
||||
Silently update two things before spawning any agent:
|
||||
|
||||
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, skip silently.
|
||||
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**: edit the `Last Updated:` field in the story header to today's date (format: `YYYY-MM-DD`). If the field does not exist in the story header, add it after the `Status:` line. This enables sprint-status staleness detection for this story.
|
||||
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.
|
||||
|
||||
---
|
||||
|
||||
## Phase 3: Route to the Right Programmer
|
||||
|
||||
Based on the story's **Layer**, **Type**, and **system name**, determine which
|
||||
specialist to spawn via Task.
|
||||
specialist to spawn via `Agent`.
|
||||
|
||||
**Config/Data stories — skip agent spawning entirely:**
|
||||
If the story's Type is `Config/Data`, no programmer agent or engine specialist is needed. Jump directly to Phase 4 (Config/Data note). The implementation is a data file edit — no routing table evaluation, no engine specialist.
|
||||
@@ -155,40 +252,111 @@ If the story's Type is `Config/Data`, no programmer agent or engine specialist i
|
||||
|
||||
### Engine specialist — always spawn as secondary for code stories
|
||||
|
||||
Read the `Engine Specialists` section of `.claude/docs/technical-preferences.md`
|
||||
to get the configured primary specialist. Spawn them alongside the primary agent
|
||||
when the story involves engine-specific APIs, patterns, or the ADR has HIGH
|
||||
engine risk.
|
||||
**Read the `specialists` block from `project.yaml` directly — it is not in
|
||||
the `resolve_config` output at the top of this skill..** `resolve_config` does not emit
|
||||
`specialists.*`; the five skills that already consume it (`/adopt`,
|
||||
`/code-review`, `/design-system`, `/gate-check`, `/team-ui`) all read the block
|
||||
out of `project.yaml` themselves, and so does this one. Adding it to the
|
||||
frontmatter key list would fail the gate that asserts every requested key is one
|
||||
`resolve_config` actually emits.
|
||||
|
||||
`/setup-engine` writes the block, and it is the project's own answer to "which
|
||||
specialist implements here" — resolved from the engine *and the language*, which
|
||||
`engine.name` alone cannot tell you. Resolve in this order:
|
||||
|
||||
1. **`specialists.code`** — the language/code specialist, and the right secondary
|
||||
for an implementation story. This is the value that distinguishes a Godot C#
|
||||
project (`godot-csharp-specialist`) from a Godot GDScript one
|
||||
(`godot-gdscript-specialist`); `engine.name` is `Godot` for both.
|
||||
2. **`specialists.shader`** when the story touches shaders or materials, and
|
||||
**`specialists.ui`** when the story's Type is `UI` — in addition to, not
|
||||
instead of, `specialists.code`.
|
||||
3. **The generic `<engine>-specialist`** — derived from `engine.name`
|
||||
(Godot→`godot-specialist`, Unity→`unity-specialist`,
|
||||
Unreal→`unreal-specialist`) — for architecture-level and broad engine
|
||||
concerns, and as the fallback when the `specialists` block is absent.
|
||||
4. If `engine.name` is also absent or empty, read the Primary line of the
|
||||
`## Engine Specialists` section of `.claude/docs/technical-preferences.md`.
|
||||
|
||||
**A value of `null` means UNSET — treat that key as absent and fall through to
|
||||
the generic specialist. Never spawn it as an agent name.** The config reader
|
||||
returns the four-character string `"null"`, which is not empty and therefore
|
||||
reads as configured; `null`, empty and missing are the same state here. (This is
|
||||
the same caveat `/code-review` Phase 2 carries, for the same reason.)
|
||||
|
||||
Spawn the resolved specialist alongside the primary agent when the story involves
|
||||
engine-specific APIs, patterns, or the ADR has HIGH engine risk.
|
||||
|
||||
The full roster, for reference when no `specialists` block exists:
|
||||
|
||||
| Engine | Specialist agents available |
|
||||
|--------|----------------------------|
|
||||
| Godot 4 | `godot-specialist`, `godot-gdscript-specialist`, `godot-shader-specialist` |
|
||||
| Unity | `unity-specialist`, `unity-ui-specialist`, `unity-shader-specialist` |
|
||||
| Godot 4 | `godot-specialist`, `godot-gdscript-specialist`, `godot-csharp-specialist`, `godot-shader-specialist`, `godot-gdextension-specialist` |
|
||||
| Unity | `unity-specialist`, `unity-ui-specialist`, `unity-shader-specialist`, `unity-dots-specialist`, `unity-addressables-specialist` |
|
||||
| Unreal Engine | `unreal-specialist`, `ue-gas-specialist`, `ue-blueprint-specialist`, `ue-umg-specialist`, `ue-replication-specialist` |
|
||||
|
||||
> **Do not pick from this table when `specialists` is set.** The table lists what
|
||||
> *exists* for an engine; the block records what this project *chose*. Reading the
|
||||
> table instead of the block is how a Godot C# project ends up reviewed by the
|
||||
> GDScript specialist.
|
||||
|
||||
**When engine risk is HIGH** (from the ADR or VERSION.md): always spawn the engine
|
||||
specialist, even for non-engine-facing stories. High risk means the ADR records
|
||||
assumptions about post-cutoff engine APIs that need expert verification.
|
||||
|
||||
> **Read the risk, do not trust the story card alone.** If the story's `Risk`
|
||||
> field is absent, or says `NOT ASSESSED`, **or disagrees with
|
||||
> `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
|
||||
> from the same file, so the two should agree; this check is what catches it when
|
||||
> they do not.
|
||||
|
||||
---
|
||||
|
||||
## Phase 4: Implement
|
||||
|
||||
Spawn the chosen programmer agent(s) via Task with the full context package:
|
||||
Spawn the chosen programmer agent(s) via `Agent` with the full context package:
|
||||
|
||||
Brief the agent with file paths and targeted reading instructions — do not serialize document content into the Task prompt. The agent reads what it needs directly:
|
||||
Brief the agent with file paths and targeted reading instructions — do not serialize document content into the `Agent` prompt. The agent reads what it needs directly.
|
||||
|
||||
1. **Story file**: `[story-path]` — read in full
|
||||
> **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
|
||||
> 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
|
||||
> confirmed missing.
|
||||
>
|
||||
> **Say which items you dropped, and say it to both readers.** The rule item 7
|
||||
> already carries applies unchanged to items 2–4: *an omitted item and a
|
||||
> forgotten one are indistinguishable to the agent.* They are equally
|
||||
> indistinguishable to the user reading the Phase 6 summary.
|
||||
> - **To the agent**, in the prompt: *"No TR registry entry is passed for this
|
||||
> story — `docs/architecture/tr-registry.yaml` does not exist at this tier.
|
||||
> 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.`
|
||||
>
|
||||
> Without this, a `standard` run where the registry legitimately does not exist
|
||||
> and one where `/architecture-review` was supposed to bootstrap it and nobody
|
||||
> did produce **identical output**.
|
||||
|
||||
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**: `docs/architecture/[adr-file].md` — read the **Decision** and **Implementation Guidelines** sections only
|
||||
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.
|
||||
4. **Control manifest**: `docs/architecture/control-manifest.md` — read rules for the **[layer]** layer only
|
||||
5. **Engine preferences**: `.claude/docs/technical-preferences.md` — read naming conventions and performance budgets
|
||||
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): 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. 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, 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.
|
||||
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:
|
||||
- Create or modify files in `src/` following the ADR guidelines
|
||||
- Create or modify files under the **resolved code root** following the ADR guidelines. Resolve it per `.claude/docs/code-root-resolution.md` — `src/` is the Godot row, `Assets/Scripts/<System>/` is Unity's, `Source/<Module>/<System>/` is Unreal's. **If the code root cannot be resolved, do not write: report it and stop.** Selecting the engine specialist above is NOT the same as resolving the code root
|
||||
- Respect all Required and Forbidden patterns from the control manifest
|
||||
- Stay within the story's Out of Scope boundaries (do not touch unrelated files)
|
||||
- Write clean, doc-commented public APIs
|
||||
@@ -202,9 +370,12 @@ changed from/to.
|
||||
|
||||
### Visual/Feel stories
|
||||
|
||||
Spawn `gameplay-programmer` to implement the code/animation calls. Note that
|
||||
Visual/Feel acceptance criteria cannot be auto-verified — the "does it feel right?"
|
||||
check happens in `/story-done` via manual confirmation.
|
||||
Spawn `gameplay-programmer` to implement the code/animation calls. The *look*
|
||||
half of the acceptance criteria — layout, clipping, presence, colour — is
|
||||
verified in Phase 6 step 4 by launching the build and retaining a screenshot;
|
||||
it is not deferred. The *feel* half — timing, weight, responsiveness — is not
|
||||
something a still can show: say which half the run covered, and leave feel to
|
||||
`/team-qa`.
|
||||
|
||||
---
|
||||
|
||||
@@ -212,24 +383,117 @@ check happens in `/story-done` via manual confirmation.
|
||||
|
||||
The test requirement was included in the Phase 4 programmer agent brief (item 7). This phase summarizes what evidence each story type requires — used when collecting the Phase 6 summary.
|
||||
|
||||
| Story Type | Required Evidence | Notes |
|
||||
|---|---|---|
|
||||
| **Logic** | Automated unit test at path from story's Test Evidence section | BLOCKING — included in Phase 4 agent brief |
|
||||
| **Integration** | Integration test OR documented playtest record | BLOCKING — included in Phase 4 agent brief |
|
||||
| **Visual/Feel** | Evidence doc at `production/qa/evidence/[slug]-evidence.md` | ADVISORY — note in Phase 6 summary |
|
||||
| **UI** | Manual walkthrough doc or interaction test | ADVISORY — note in Phase 6 summary |
|
||||
| **Config/Data** | None — smoke check serves as evidence | N/A |
|
||||
**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.
|
||||
|
||||
For Visual/Feel and UI stories, include in the Phase 6 summary: "Manual evidence required at `production/qa/evidence/[slug]-evidence.md` before this story can be fully closed."
|
||||
> **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:
|
||||
>
|
||||
> > *Test evidence: **waived** at `qa.level: minimal` — no test was required or
|
||||
> > written for this story.*
|
||||
>
|
||||
> Without it, a minimal-tier summary that simply lacks a tests row is
|
||||
> indistinguishable from a `standard`-tier run where the programmer forgot to
|
||||
> write them — and the permissive reading is the one that gets believed.
|
||||
|
||||
Otherwise:
|
||||
|
||||
**Resolve the gate level for this story's type** from `testing.strict` in
|
||||
`project.yaml`. BLOCKING means a missing test marks the story unverifiable;
|
||||
ADVISORY means a missing test is noted but does not block:
|
||||
|
||||
1. Map the Story Type to a `testing.strict` key — Logic→`logic`,
|
||||
Integration→`integration`, Visual/Feel→`visual`, UI→`ui`, Config/Data→`config`.
|
||||
Take `testing.strict.<key>` from the **the resolved-config block at the top of this skill**, not from
|
||||
`project.yaml` directly. If its value is `true` (case-insensitive) →
|
||||
BLOCKING; if `false` → ADVISORY; `unset` → fall through.
|
||||
|
||||
> `testing.strict.*` is locally overridable (`/settings --local
|
||||
> testing.strict.logic=false`). Reading `project.yaml` on its own ignores
|
||||
> `project.local.yaml` entirely, so the override is accepted and then does
|
||||
> nothing. `resolve_config` merges the two.
|
||||
2. Else read `testing.strict` as a plain boolean (legacy single-value form) — if
|
||||
its value is `true` or `false`, it applies to every type.
|
||||
3. Else use the **Default Gate Level** column below.
|
||||
|
||||
Only `true` and `false` (case-insensitive) are recognized at steps 1–2. A key
|
||||
that is present but holds any other value — `maybe`, `1`, `yes`, etc. — is
|
||||
treated as unset: continue to the next step, and surface the unrecognized value
|
||||
to the user.
|
||||
|
||||
| Story Type | Required Evidence | Default Gate Level |
|
||||
|---|---|---|
|
||||
| **Logic** | Automated unit test at path from story's Test Evidence section | BLOCKING |
|
||||
| **Integration** | Integration test OR documented playtest record | BLOCKING |
|
||||
| **Visual/Feel** | Retained screenshot + evidence doc at `production/qa/evidence/[slug]-evidence.md` | BLOCKING |
|
||||
| **UI** | Retained screenshot of each screen touched, in `production/qa/evidence/` | BLOCKING |
|
||||
| **Config/Data** | None — smoke check serves as evidence | ADVISORY |
|
||||
|
||||
The test is written alongside the implementation (Phase 4, item 7) regardless of
|
||||
the gate level — strictness controls only how a *missing* test is reported in the
|
||||
Phase 6 summary. At a BLOCKING level, a missing test is flagged "story
|
||||
unverifiable — test required before `/story-done`". At an ADVISORY level it is
|
||||
noted as a recommendation. The **Default Gate Level** column applies when
|
||||
`testing.strict` is unset.
|
||||
|
||||
Visual/Feel and UI default to **BLOCKING**: for a game the rendered result is the
|
||||
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."
|
||||
|
||||
---
|
||||
|
||||
## Phase 6: Collect and Summarise
|
||||
|
||||
After the programmer agent(s) complete, collect:
|
||||
### First: did the agent actually finish?
|
||||
|
||||
**Do not assume completion.** A programmer agent can stop at its turn limit
|
||||
mid-edit, and the work it leaves behind can be syntactically broken — a helper
|
||||
called but never defined, an import half-moved. Its partial report reads like
|
||||
progress, and this phase's summary would print "Implementation Complete" over
|
||||
code that does not load.
|
||||
|
||||
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.
|
||||
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.
|
||||
4. **Run it and look.** A parse check is not a run. For every story that
|
||||
changes something a player can see — every Visual/Feel and UI story, and any
|
||||
Logic, Integration or Config/Data story with a surface — launch the build
|
||||
via `commands.run`, straight into the scene or map the story touched, and
|
||||
retain a screenshot under `production/qa/evidence/[story-slug]/`. Then
|
||||
`Read` the image and compare it to the acceptance criteria: clipped text,
|
||||
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`.
|
||||
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.
|
||||
**`NOT VERIFIED` is a blocker at the default gate level for Visual/Feel and
|
||||
UI, not a note** — `/story-done` reads this line. This step is **not waived
|
||||
at `qa.level: minimal`**; tests are, the look is not.
|
||||
|
||||
**If INCOMPLETE:** say so as the headline, list what exists so far, name the
|
||||
specific breakage, and offer to resume the agent. Do **not** emit
|
||||
"Implementation Complete", and do not advance the story's status.
|
||||
|
||||
### Then collect:
|
||||
|
||||
- Files created or modified (with paths)
|
||||
- Test file created (path and number of test functions written)
|
||||
- **Verification result** — what was run, and its outcome (or why it could not run)
|
||||
- Test file created (path and number of test functions written) — **or**, at
|
||||
`qa.level: minimal`, the waiver line from Phase 5
|
||||
- Any deviations from the story's Out of Scope boundary (flag these)
|
||||
- Any questions or blockers the agent surfaced
|
||||
- Any engine-specific risks the specialist flagged
|
||||
@@ -240,19 +504,24 @@ Present a concise implementation summary:
|
||||
## Implementation Complete: [Story Title]
|
||||
|
||||
**Files changed**:
|
||||
- `src/[path]` — created / modified ([brief description])
|
||||
- `tests/[path]` — test file ([N] test functions)
|
||||
- `<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*
|
||||
|
||||
**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`
|
||||
|
||||
**Acceptance criteria covered**:
|
||||
- [x] [criterion] — implemented in [file:function]
|
||||
- [x] [criterion] — covered by test [test_name]
|
||||
- [ ] [criterion] — DEFERRED: requires playtest (Visual/Feel)
|
||||
- [x] [criterion] — OBSERVED in `production/qa/evidence/[slug]/01-[what].png` (Visual/UI look)
|
||||
- [ ] [criterion] — DEFERRED: requires playtest (Visual/Feel *feel* — timing, weight; a still cannot show it)
|
||||
|
||||
**Deviations from scope**: [None] or [list files touched outside story boundary]
|
||||
**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. `/story-done` will re-run them automatically, but a failing test discovered there means returning to implementation context.
|
||||
**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.
|
||||
|
||||
Ready for: `/code-review [file1] [file2]` then `/story-done [story-path]`
|
||||
```
|
||||
@@ -278,26 +547,32 @@ Create `active.md` if it does not exist. Confirm: "Session state updated."
|
||||
|
||||
## Error Recovery Protocol
|
||||
|
||||
If any spawned agent (via Task) returns BLOCKED, errors, or cannot complete:
|
||||
**First, verify the artifact.** If the return contract named a path, check the
|
||||
path exists before treating the phase as done — **a named artifact that is not
|
||||
on disk is a failed phase, however fluent the response reads.** An agent can
|
||||
burn a full phase and return a plausible preamble having written nothing, which
|
||||
is neither BLOCKED nor an error nor "cannot complete", so the trigger below
|
||||
never fires. Resume it naming the unmet contract; the context is
|
||||
usually still there.
|
||||
|
||||
1. **Surface immediately**: Report "[AgentName]: BLOCKED — [reason]" to the user before continuing to dependent phases
|
||||
2. **Assess dependencies**: Check whether the blocked agent's output is required by subsequent phases. If yes, do not proceed past that dependency point without user input.
|
||||
3. **Offer options** via AskUserQuestion with choices:
|
||||
- Skip this agent and note the gap in the final report
|
||||
- Retry with narrower scope
|
||||
- Stop here and resolve the blocker first
|
||||
4. **Always produce a partial report** — output whatever was completed. Never discard work because one agent blocked.
|
||||
If any spawned agent returns BLOCKED, errors, or cannot complete: **surface it
|
||||
immediately, don't proceed past a dependency it blocks, and always produce a
|
||||
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
|
||||
- ADR status is Proposed → do not implement; run `/architecture-decision` first
|
||||
- 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)
|
||||
- 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
|
||||
|
||||
## Collaborative Protocol
|
||||
|
||||
- **File writes are delegated** — all source code, test files, and evidence docs are written by sub-agents spawned via Task. Each sub-agent enforces the "May I write to [path]?" protocol individually. This orchestrator does not write files directly.
|
||||
**Applies in `collaborative` mode (the default).** For `guided` and
|
||||
`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.
|
||||
- **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.
|
||||
@@ -308,8 +583,9 @@ Common blockers:
|
||||
the story requires touching an out-of-scope file, stop and surface it:
|
||||
"Implementing [criterion] requires modifying [file], which is out of scope.
|
||||
Shall I proceed or create a separate story?"
|
||||
- **Test is not optional for Logic/Integration** — do not mark implementation
|
||||
complete without the test file existing
|
||||
- **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`
|
||||
- **Ask before large structural decisions** — if the story requires an
|
||||
|
||||
Reference in New Issue
Block a user