Release 1.1.3 — long skills keep their later steps

Fix release for 1.1.2: the 14 longest skills keep their later phases
after a compaction, a question nobody answered is never taken as an
answer, settings read the same from a subfolder, the commit check works
for a project in a subfolder of a larger repository, every skill opens
with a title, and the shipped allow rules no longer approve deleting a
branch or writing files without asking. Details in CHANGELOG.md; upgrade
steps in UPGRADING.md (v1.1.2 → v1.1.3).

Refs #83
Refs #133

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0185en4t76fPn7315q4c3nko
This commit is contained in:
Donchitos
2026-10-08 17:52:48 +11:00
co-authored by Claude Opus 5.5
parent b21fa0f7f2
commit be8993bbc5
231 changed files with 12000 additions and 10527 deletions
+7 -487
View File
@@ -13,7 +13,6 @@ Resolved above — use as-is. `/adopt` also inspects `project.yaml` and the lega
config files directly when reporting and writing migration state; that raw
inspection is deliberate and separate from the resolved values above.
# Adopt — Brownfield Template Adoption
This skill audits an existing project's artifacts for **format compliance** with
@@ -53,510 +52,31 @@ only the required docs/sections (optional sections are informational, not gaps);
## Phase 1: Detect Project State
Emit one line before reading: `"Scanning project artifacts..."` — this confirms the
skill is running during the silent read phase.
Then read silently before presenting anything else.
### Existence check
- `project.stage` in `project.yaml` (fallback `production/stage.txt`) — if either is present, use that value (authoritative phase)
- `design/gdd/game-concept.md` (or, at the minimal tier, `design/game-brief.md`) — concept exists?
- `design/gdd/systems-index.md` — systems index exists?
- Count GDD files: `design/gdd/*.md` (excluding game-concept.md and systems-index.md)
- Count ADR files: `docs/architecture/adr-*.md`
- Count story files: `production/epics/**/*.md` (excluding EPIC.md)
- `project.yaml` (`engine.name`) / `.claude/docs/technical-preferences.md` — engine configured?
- `docs/engine-reference/` — engine reference docs present?
- Glob `docs/adoption-plan-*.md` — note the filename of the most recent prior plan if any exist
### Infer phase (if no project.stage / stage.txt)
Use the same heuristic as `/project-stage-detect`:
- 10+ source files in the code root → Production
- Stories in `production/epics/` → Pre-Production
- ADRs exist → Technical Setup
- systems-index.md exists → Systems Design
- game-concept.md (or `design/game-brief.md`) exists → Concept
- Nothing → Fresh (not a brownfield project — suggest `/start`)
If the project appears fresh (no artifacts at all), use `AskUserQuestion`:
- "This looks like a fresh project — no existing artifacts found. `/adopt` is for
projects with work to migrate. What would you like to do?"
- "Run `/start` — begin guided first-time onboarding"
- "My artifacts are in a non-standard location — help me find them"
- "Cancel"
Then stop — do not proceed with the audit regardless of which option the user picks
(each option leads to a different skill or manual investigation).
Report: "Detected phase: [phase]. Found: [N] GDDs, [M] ADRs, [P] stories."
---
**Read `references/1-detect.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 2: Format Audit
For each artifact type in scope (based on argument mode **and the resolved
workflow tier**), check not just that the file exists but that it contains the
internal structure the template requires. At `minimal`, scope the audit to
`design/game-brief.md` — do not audit for GDDs, ADRs, or UX specs (they are not expected).
Steps 2e (the Engine reference row only), 2f (project config) and 2g (v1.0
migration check) run at every tier.
### 2a: GDD Format Audit
**Gather section presence deterministically — do not read the GDDs to count
headings.** For each GDD discovered in Phase 1, pass its path explicitly to the
structure-check script:
```
Bash: bash .claude/scripts/gdd-structure-check.sh [path-to-gdd]
```
**Pass paths one at a time; do not invoke it bare.** The no-argument form sweeps
`design/gdd/` only, and a brownfield project's GDDs are not guaranteed to live
there — pass whatever paths Phase 1 found. The script prints a `PRESENT:` list
and, when applicable, an `ABSENT:` list per file. It reports **presence only**
and makes no REQUIRED/ADVISORY judgment (that is the tier logic below), and it
already accepts `## Detailed Design` as satisfying the `Detailed Rules`
requirement, so do not flag that alias as missing.
If the script prints `Not found:` for a path or errors, that is a **discovery
failure, not a format gap** — report it as "could not audit [path]" and do not
count it as a missing-sections finding.
**Then apply the workflow tier** resolved above to each file's PRESENT/ABSENT
lists. Which sections are **required** (a miss = gap) vs **advisory** (a miss =
informational):
- **`full`** — all 8 sections are required.
- **`standard`** — the 5 required (Overview, Detailed Rules, Edge Cases,
Dependencies, Acceptance Criteria) + Formulas for any system that defines
numeric rules (rates, curves, thresholds, costs — the system's `Category` is a
hint, not the test); Player Fantasy and Tuning Knobs are advisory.
- **`minimal`** — GDDs are not expected; audit `design/game-brief.md` instead,
against `.claude/docs/templates/game-brief.md`: each of the six required fields
present and not a placeholder; the three one-liners advisory. Any GDD that
does exist is checked at the `standard` bar, advisorily.
The script's 8 canonical labels are: Overview, Player Fantasy, Detailed Rules,
Formulas, Edge Cases, Dependencies, Tuning Knobs, Acceptance Criteria.
A section reported PRESENT can still be an empty heading. For each GDD, also
record with a targeted grep (not a full read):
- Placeholder-only sections — `Grep pattern="\[To be designed\]"` (or an
equivalent empty/single-line body) marks a present-but-unwritten section.
- The `**Status**:` header field — `Grep pattern="^>?[[:space:]]*\*\*Status\*\*:"`.
Valid values: `Draft`, `In Design`, `Designed`, `In Review`, `Approved`,
`Implemented`, `Needs Revision`.
> **The `>?` is load-bearing, and so are `Draft`/`Implemented`.** Both emitters
> write this field inside a blockquote — `.claude/docs/templates/game-design-document.md`
> and `/design-system` produce `> **Status**: …` — so an anchor of
> `^\*\*Status\*\*:` matches nothing and reports *every* template-compliant GDD
> as missing its Status. The template's own value list offers `Draft` and
> `Implemented`, so both must count as valid.
### 2b: ADR Format Audit
For each ADR file found, check for these critical sections:
| Section | Impact if missing |
|---|---|
| `## Status` | **BLOCKING** — `/story-readiness` ADR status check silently passes everything |
| `## ADR Dependencies` | HIGH — dependency ordering in `/architecture-review` breaks |
| `## Engine Compatibility` | HIGH — post-cutoff API risk is unknown |
| `## GDD Requirements Addressed` | MEDIUM — traceability matrix loses coverage |
| `## Performance Implications` | LOW — not pipeline-critical |
For each ADR, record: which sections present, which missing, current Status value
if the Status section exists.
### 2c: systems-index.md Format Audit
If `design/gdd/systems-index.md` exists:
1. **Parenthetical status values** — Grep for any Status cell containing
parentheses: `"Needs Revision ("`, `"In Progress ("`, etc.
These break exact-string matching in `/gate-check`, `/create-stories`,
and `/architecture-review`. **BLOCKING.**
2. **Valid status values** — check that Status column values are only from:
`Not Started`, `In Progress`, `In Review`, `Designed`, `Approved`, `Needs Revision`
Flag any unrecognised values.
3. **Column structure** — check that the table has at minimum: System name,
Layer, Priority, Status columns. Missing columns degrade skill functionality.
### 2d: Story Format Audit
For each story file found:
- **`Manifest Version:` field** — present in story header? (LOW — auto-passes if absent)
- **TR-ID reference** — does story contain `TR-[a-z]+-[0-9]+` pattern? (MEDIUM — no staleness tracking)
- **ADR reference** — does story reference at least one ADR? (check for `ADR-` pattern)
- **Status field** — present and readable?
- **Acceptance criteria** — does the story have a checkbox list (`- [ ]`)?
### 2e: Infrastructure Audit
| Artifact | Path | Impact if missing |
|---|---|---|
| TR registry | `docs/architecture/tr-registry.yaml` | HIGH — no stable requirement IDs |
| Control manifest | `docs/architecture/control-manifest.md` | HIGH — no layer rules for stories |
| Manifest version stamp | In manifest header: `Manifest Version:` | MEDIUM — staleness checks blind |
| Sprint status | `production/sprint-status.yaml` | MEDIUM — `/sprint-status` falls back to markdown |
| Stage file | `project.stage` in `project.yaml` (fallback `production/stage.txt`) | MEDIUM — phase auto-detect unreliable |
| Engine reference | `docs/engine-reference/[engine]/VERSION.md` | HIGH — ADR engine checks blind |
| Architecture traceability | `docs/architecture/requirements-traceability.md` | MEDIUM — no persistent matrix |
At `workflow: minimal` only the Engine reference row applies. The TR registry,
control manifest and its version stamp, sprint status, stage file and
traceability matrix are not on the minimal path, so their absence is not a gap.
### 2f: Project Config Audit
Read `project.yaml` (the primary config store) and `.claude/docs/technical-preferences.md` (legacy mirror). A setting counts as configured if EITHER source has a real value (in technical-preferences.md, `[TO BE CONFIGURED]` means unconfigured):
- `engine.name`/`version`/`language`/`rendering`/`physics` (else the Engine/Language/Rendering/Physics fields) → HIGH if unconfigured in both (ADR skills fail)
- `naming.*` (else Naming conventions) → MEDIUM
- `performance.*` (else Performance budgets) → MEDIUM
- Forbidden Patterns, Allowed Libraries (technical-preferences.md only — not migrated to project.yaml) → LOW (starts empty by design)
### 2g: v1.0 Migration Check
A project is a **v1.0 project needing migration** when `project.yaml` does NOT
exist at the repo root AND at least one legacy file does: `production/stage.txt`,
`production/review-mode.txt`, or a `.claude/docs/technical-preferences.md` with
real values.
"Real values" means one of the keys the converter actually migrates — Engine,
Language, Rendering, Physics, the naming, platform and performance fields,
Framework, or the specialists. Not merely "some bullet is filled in": the
shipped template ships one prose default (`- **Required Tests**: …`) that is
never migrated, and counting it made every fresh clone read as a v1.0 project.
Do not hand-migrate. Run the converter, which is deterministic and covered by
the framework's own test suite:
```bash
bash .claude/scripts/migrate-v1-config.sh --dry-run
```
The dry run writes nothing; record what it lists for the report. Do not run the
converter during the audit — Phase 2 reads silently. The migration is
classified BLOCKING in Phase 3, heads the plan, and **Phase 7 offers it as the
first action**: report what the dry run listed, then ask "May I run the
converter? It writes `project.yaml` and `production/migration-report.md`." If
the user approves, run it without `--dry-run`. It
writes `project.yaml` plus `production/migration-report.md` and **deletes
nothing** — the whole operation stays reversible with `git checkout`.
Then tell the user to read `production/migration-report.md` before running:
```bash
bash .claude/scripts/migrate-v1-config.sh --finalize
```
`--finalize` deletes a legacy file only after proving its value is present in
`project.yaml`; on mismatch it deletes nothing and exits 4. It never deletes
`technical-preferences.md`, which still holds Forbidden Patterns and Allowed
Libraries.
**If the script refuses with exit 3**, do not work around it. Exit 3 means one
of two things, and the message says which:
- **the values DISAGREE** — two sources of truth and no way to know which the
user edited last. Surface it and let them decide.
- **a `production/migration-report.md` is already present** — a migration ran
here, so these are post-migration leftovers and `--finalize` is the next step,
not a second `migrate`.
Both files merely *existing* is not exit 3 and must not be reported as a
conflict: `/start` writes `production/stage.txt` on every new v1.1 project as a
mirror, so agreement is the normal state. The script says
`the legacy files mirror it (values agree)` and exits 0 for that.
Classify as **BLOCKING** in Phase 3: until migration runs, every skill reads
config through the legacy fallback chain, and v1.1 settings are unavailable.
---
**Read `references/2-format-audit.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 3: Classify and Prioritise Gaps
Organise every gap found across all audits into four severity tiers:
**BLOCKING** — Will cause template skills to silently produce wrong results *right now*.
Examples: ADR missing Status field, systems-index parenthetical status values,
engine not configured when ADRs exist.
**HIGH** — Will cause stories to be generated with missing safety checks, or
infrastructure bootstrapping will fail.
Examples: ADRs missing Engine Compatibility, GDDs missing Acceptance Criteria
(stories can't be generated from them), tr-registry.yaml missing.
**MEDIUM** — Degrades quality and pipeline tracking but does not break functionality.
Examples: GDDs missing Tuning Knobs or Formulas sections, stories missing TR-IDs,
sprint-status.yaml missing.
**LOW** — Retroactive improvements that are nice-to-have but not urgent.
Examples: Stories missing Manifest Version stamps, GDDs missing Open Questions section.
Count totals per tier. If zero BLOCKING and zero HIGH gaps: report that the project
is template-compatible and only advisory improvements remain.
---
**Read `references/3-classify.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 4: Build the Migration Plan
Compose a numbered, ordered action plan. Ordering rules:
1. BLOCKING gaps first (must fix before any pipeline skill runs reliably)
2. HIGH gaps next, infrastructure before GDD/ADR content (bootstrapping needs correct formats)
3. MEDIUM gaps ordered: GDD gaps before ADR gaps before story gaps (stories depend on GDDs and ADRs)
4. LOW gaps last
For each gap, produce a plan entry with:
- A clear problem statement (one sentence, no jargon)
- The exact command to fix it, if a skill handles it
- Manual steps if it requires direct editing
- A time estimate (rough: 5 min / 30 min / 1 session)
- A checkbox `- [ ]` for tracking
**Special case — systems-index parenthetical status values:**
This is always the first item if present. Show the exact values that need changing
and the exact replacement text. Offer to fix this immediately before writing the plan.
**Special case — ADRs missing Status field:**
For each affected ADR, the fix is:
`/architecture-decision retrofit docs/architecture/adr-[NNNN]-[slug].md`
List each ADR as a separate checkable item.
**Special case — GDDs missing sections:**
For each affected GDD, list which sections are missing and the fix:
`/design-system retrofit design/gdd/[filename].md`
**Infrastructure bootstrap ordering** — always present in this sequence:
1. Fix ADR formats first (registry depends on reading ADR Status fields)
2. Run `/architecture-review` → bootstraps `tr-registry.yaml`
3. Run `/create-control-manifest` → creates manifest with version stamp
4. Run `/sprint-plan update` → creates `sprint-status.yaml`
5. Run `/gate-check [phase]` (the gate into the phase the project is in; at Concept there is none — Concept is the default stage, nothing to run) → writes `project.stage` in `project.yaml` (and legacy `stage.txt`) authoritatively
**At `workflow: minimal` the plan prescribes none of this sequence.** None of it
is on the minimal path: ADRs are not expected, the brief's build order is the
plan (no `/sprint-plan`), and nothing there runs `/gate-check`. The plan's
Step 3 says so in one line and names the path's next step instead —
`/create-stories` when no stories exist, else `/dev-story`.
**Existing stories** — note explicitly:
> "Existing stories continue to work with all template skills — all new format
> checks auto-pass when the fields are absent. They won't benefit from TR-ID
> staleness tracking or manifest version checks until they're regenerated. This
> is intentional: do not regenerate stories that are already in progress."
---
**Read `references/4-migration-plan.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 5: Present Summary and Ask to Write
Present a compact summary before writing:
```
## Adoption Audit Summary
Phase detected: [phase]
Engine: [configured / NOT CONFIGURED]
GDDs audited: [N] ([X] fully compliant, [Y] with gaps)
ADRs audited: [N] ([X] fully compliant, [Y] with gaps)
Stories audited: [N]
Gap counts:
BLOCKING: [N] — template skills will malfunction without these fixes
HIGH: [N] — unsafe to run /create-stories or /story-readiness
MEDIUM: [N] — quality degradation
LOW: [N] — optional improvements
Estimated remediation: [X blocking items × ~Y min each = roughly Z hours]
```
Before asking to write, show a **Gap Preview**:
- List every BLOCKING gap as a one-line bullet describing the actual problem
(e.g. `systems-index.md: 3 rows have parenthetical status values`,
`adr-0002.md: missing ## Status section`). No counts — show the actual items.
- Show HIGH / MEDIUM / LOW as counts only (e.g. `HIGH: 4, MEDIUM: 2, LOW: 1`).
This gives the user enough context to judge scope before committing to writing the file.
If a prior adoption plan was detected in Phase 1, add a note:
> "A previous plan exists at `docs/adoption-plan-[prior-date].md`. The new plan will
> reflect current project state — it does not diff against the prior run."
Use `AskUserQuestion`:
- "Ready to write the migration plan?"
- "Yes — write `docs/adoption-plan-[date].md`"
- "Show me the full plan preview first (don't write yet)"
- "Cancel — I'll handle migration manually"
If the user picks "Show me the full plan preview", output the complete plan as a
fenced markdown block. Then ask again with the same three options.
---
**Read `references/5-summary.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 6: Write the Adoption Plan
If approved, write `docs/adoption-plan-[date].md` with this structure:
```markdown
# Adoption Plan
> **Generated**: [date]
> **Project phase**: [phase]
> **Engine**: [name + version, or "Not configured"]
> **Template version**: v1.0+
Work through these steps in order. Check off each item as you complete it.
Re-run `/adopt` anytime to check remaining gaps.
---
## Step 1: Fix Blocking Gaps
[One sub-section per blocking gap with problem, fix command, time estimate, checkbox]
---
## Step 2: Fix High-Priority Gaps
[One sub-section per high gap]
---
## Step 3: Bootstrap Infrastructure
[At `workflow: minimal`, replace 3a–3d with one line: "Not on the minimal path —
the brief's build order is the plan. Next: `/create-stories` (or `/dev-story`
once stories exist)."]
### 3a. Register existing requirements (creates tr-registry.yaml)
Run `/architecture-review` — even if ADRs already exist, this run bootstraps
the TR registry from your existing GDDs and ADRs.
**Time**: 1 session (review can be long for large codebases)
- [ ] tr-registry.yaml created
### 3b. Create control manifest
Run `/create-control-manifest`
**Time**: 30 min
- [ ] docs/architecture/control-manifest.md created
### 3c. Create sprint tracking file
Run `/sprint-plan update`
**Time**: 5 min (if sprint plan already exists as markdown)
- [ ] production/sprint-status.yaml created
### 3d. Set authoritative project stage
Run `/gate-check [current-phase]` (the gate into the phase the project is in;
at Concept there is none — Concept is the default stage, nothing to run)
**Time**: 5 min
- [ ] `project.stage` in `project.yaml` written (legacy `production/stage.txt` also updated)
---
## Step 4: Medium-Priority Gaps
[One sub-section per medium gap]
---
## Step 5: Optional Improvements
[One sub-section per low gap]
---
## What to Expect from Existing Stories
Existing stories continue to work with all template skills. New format checks
(TR-ID validation, manifest version staleness) auto-pass when the fields are
absent — so nothing breaks. They won't benefit from staleness tracking until
regenerated. Do not regenerate stories that are in progress or done.
---
## Re-run
Run `/adopt` again after completing Step 3 to verify all blocking and high gaps
are resolved. The new run will reflect the current state of the project.
```
---
## Phase 6b: Report Review Mode
**Do not write a review mode.** `modes.review_mode` is one of the six knobs
`modes.rigor` fronts: pinning it in `project.yaml` shadows the rigor expansion, and
the legacy `production/review-mode.txt` sits *above* that expansion in resolution,
so either write would freeze director-review depth for good — the rule `/start`
and `project.yaml`'s header comment both state.
Report the value the bootstrap above resolved instead: "Review mode resolves to
`[value]` — from `modes.rigor`, unless something pins it." If the user wants a
different depth, point them to changing `modes.rigor`, or to pinning it on purpose
with `/settings --local modes.review_mode=<full|lean|solo>` (a personal override in
`project.local.yaml`).
---
**Read `references/6-write.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 7: Offer First Action
After writing the plan, don't stop there. Pick the single highest-priority gap
and offer to handle it immediately using `AskUserQuestion`. Choose the first
branch that applies:
**If Phase 2g found a v1.0 project needing migration:** offer the converter run
described there — report what the dry run listed and ask "May I run the
converter? It writes `project.yaml` and `production/migration-report.md`."
Every other fix reads config through it, so it comes first.
**If there are parenthetical status values in systems-index.md:**
Use `AskUserQuestion`:
- "The most urgent fix is `systems-index.md` — [N] rows have parenthetical status
values (e.g. `Needs Revision (see notes)`) that break /gate-check,
/create-stories, and /architecture-review right now. I can fix these in-place."
- "Fix it now — edit systems-index.md"
- "I'll fix it myself"
- "Done — leave me with the plan"
**If ADRs are missing `## Status` (and no parenthetical issue):**
Use `AskUserQuestion`:
- "The most urgent fix is adding `## Status` to [N] ADR(s): [list filenames].
Without it, /story-readiness silently passes all ADR checks. Start with
[first affected filename]?"
- "Yes — retrofit [first affected filename] now"
- "Retrofit all [N] ADRs one by one"
- "I'll handle ADRs myself"
**If GDDs are missing Acceptance Criteria (and no blocking issues above):**
Use `AskUserQuestion`:
- "The most urgent gap is missing Acceptance Criteria in [N] GDD(s):
[list filenames]. Without them, /create-stories can't generate stories.
Start with [highest-priority GDD filename]?"
- "Yes — add Acceptance Criteria to [GDD filename] now"
- "Do all [N] GDDs one by one"
- "I'll handle GDDs myself"
**Otherwise, if any BLOCKING or HIGH gap remains** (one no branch above names —
e.g. a missing TR registry):
Use `AskUserQuestion`:
- "The most urgent remaining gap is [first BLOCKING or HIGH item in the plan] —
[one line on what it breaks]. Start on it now?"
- "Yes — start on [item]"
- "Show me that plan item first"
- "Done — leave me with the plan"
**If no BLOCKING or HIGH gaps exist:**
Use `AskUserQuestion`:
- "No blocking gaps — this project is template-compatible. What next?"
- "Walk me through the medium-priority improvements"
- "Run /project-stage-detect for a broader health check"
- "Done — I'll work through the plan at my own pace"
> **Adoption plan saved to `docs/adoption-plan-[date].md`.** Re-run `/adopt` at any time to re-check remaining gaps as you complete them.
---
**Read `references/7-first-action.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Collaborative Protocol
@@ -0,0 +1,45 @@
# /adopt — Phase 1: Detect Project State
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 1: Detect Project State
Emit one line before reading: `"Scanning project artifacts..."` — this confirms the
skill is running during the silent read phase.
Then read silently before presenting anything else.
### Existence check
- `project.stage` in `project.yaml` (fallback `production/stage.txt`) — if either is present, use that value (authoritative phase)
- `design/gdd/game-concept.md` (or, at the minimal tier, `design/game-brief.md`) — concept exists?
- `design/gdd/systems-index.md` — systems index exists?
- Count GDD files: `design/gdd/*.md` (excluding game-concept.md and systems-index.md)
- Count ADR files: `docs/architecture/adr-*.md`
- Count story files: `production/epics/**/*.md` (excluding EPIC.md)
- `project.yaml` (`engine.name`) / `.claude/docs/technical-preferences.md` — engine configured?
- `docs/engine-reference/` — engine reference docs present?
- Glob `docs/adoption-plan-*.md` — note the filename of the most recent prior plan if any exist
### Infer phase (if no project.stage / stage.txt)
Use the same heuristic as `/project-stage-detect`:
- 10+ source files in the code root → Production
- Stories in `production/epics/` → Pre-Production
- ADRs exist → Technical Setup
- systems-index.md exists → Systems Design
- game-concept.md (or `design/game-brief.md`) exists → Concept
- Nothing → Fresh (not a brownfield project — suggest `/start`)
If the project appears fresh (no artifacts at all), use `AskUserQuestion`:
- "This looks like a fresh project — no existing artifacts found. `/adopt` is for
projects with work to migrate. What would you like to do?"
- "Run `/start` — begin guided first-time onboarding"
- "My artifacts are in a non-standard location — help me find them"
- "Cancel"
Then stop — do not proceed with the audit regardless of which option the user picks
(each option leads to a different skill or manual investigation).
Report: "Detected phase: [phase]. Found: [N] GDDs, [M] ADRs, [P] stories."
---
@@ -0,0 +1,200 @@
# /adopt — Phase 2: Format Audit
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 2: Format Audit
**In this file:**
- 2a: GDD Format Audit
- 2b: ADR Format Audit
- 2c: systems-index.md Format Audit
- 2d: Story Format Audit
- 2e: Infrastructure Audit
- 2f: Project Config Audit
- 2g: v1.0 Migration Check
For each artifact type in scope (based on argument mode **and the resolved
workflow tier**), check not just that the file exists but that it contains the
internal structure the template requires. At `minimal`, scope the audit to
`design/game-brief.md` — do not audit for GDDs, ADRs, or UX specs (they are not expected).
Steps 2e (the Engine reference row only), 2f (project config) and 2g (v1.0
migration check) run at every tier.
### 2a: GDD Format Audit
**Gather section presence deterministically — do not read the GDDs to count
headings.** For each GDD discovered in Phase 1, pass its path explicitly to the
structure-check script:
```
Bash: bash .claude/scripts/gdd-structure-check.sh [path-to-gdd]
```
**Pass paths one at a time; do not invoke it bare.** The no-argument form sweeps
`design/gdd/` only, and a brownfield project's GDDs are not guaranteed to live
there — pass whatever paths Phase 1 found. The script prints a `PRESENT:` list
and, when applicable, an `ABSENT:` list per file. It reports **presence only**
and makes no REQUIRED/ADVISORY judgment (that is the tier logic below), and it
already accepts `## Detailed Design` as satisfying the `Detailed Rules`
requirement, so do not flag that alias as missing.
If the script prints `Not found:` for a path or errors, that is a **discovery
failure, not a format gap** — report it as "could not audit [path]" and do not
count it as a missing-sections finding.
**Then apply the workflow tier** resolved above to each file's PRESENT/ABSENT
lists. Which sections are **required** (a miss = gap) vs **advisory** (a miss =
informational):
- **`full`** — all 8 sections are required.
- **`standard`** — the 5 required (Overview, Detailed Rules, Edge Cases,
Dependencies, Acceptance Criteria) + Formulas for any system that defines
numeric rules (rates, curves, thresholds, costs — the system's `Category` is a
hint, not the test); Player Fantasy and Tuning Knobs are advisory.
- **`minimal`** — GDDs are not expected; audit `design/game-brief.md` instead,
against `.claude/docs/templates/game-brief.md`: each of the six required fields
present and not a placeholder; the three one-liners advisory. Any GDD that
does exist is checked at the `standard` bar, advisorily.
The script's 8 canonical labels are: Overview, Player Fantasy, Detailed Rules,
Formulas, Edge Cases, Dependencies, Tuning Knobs, Acceptance Criteria.
A section reported PRESENT can still be an empty heading. For each GDD, also
record with a targeted grep (not a full read):
- Placeholder-only sections — `Grep pattern="\[To be designed\]"` (or an
equivalent empty/single-line body) marks a present-but-unwritten section.
- The `**Status**:` header field — `Grep pattern="^>?[[:space:]]*\*\*Status\*\*:"`.
Valid values: `Draft`, `In Design`, `Designed`, `In Review`, `Approved`,
`Implemented`, `Needs Revision`.
> **The `>?` is load-bearing, and so are `Draft`/`Implemented`.** Both emitters
> write this field inside a blockquote — `.claude/docs/templates/game-design-document.md`
> and `/design-system` produce `> **Status**: …` — so an anchor of
> `^\*\*Status\*\*:` matches nothing and reports *every* template-compliant GDD
> as missing its Status. The template's own value list offers `Draft` and
> `Implemented`, so both must count as valid.
### 2b: ADR Format Audit
For each ADR file found, check for these critical sections:
| Section | Impact if missing |
|---|---|
| `## Status` | **BLOCKING** — `/story-readiness` ADR status check silently passes everything |
| `## ADR Dependencies` | HIGH — dependency ordering in `/architecture-review` breaks |
| `## Engine Compatibility` | HIGH — post-cutoff API risk is unknown |
| `## GDD Requirements Addressed` | MEDIUM — traceability matrix loses coverage |
| `## Performance Implications` | LOW — not pipeline-critical |
For each ADR, record: which sections present, which missing, current Status value
if the Status section exists.
### 2c: systems-index.md Format Audit
If `design/gdd/systems-index.md` exists:
1. **Parenthetical status values** — Grep for any Status cell containing
parentheses: `"Needs Revision ("`, `"In Progress ("`, etc.
These break exact-string matching in `/gate-check`, `/create-stories`,
and `/architecture-review`. **BLOCKING.**
2. **Valid status values** — check that Status column values are only from:
`Not Started`, `In Progress`, `In Review`, `Designed`, `Approved`, `Needs Revision`
Flag any unrecognised values.
3. **Column structure** — check that the table has at minimum: System name,
Layer, Priority, Status columns. Missing columns degrade skill functionality.
### 2d: Story Format Audit
For each story file found:
- **`Manifest Version:` field** — present in story header? (LOW — auto-passes if absent)
- **TR-ID reference** — does story contain `TR-[a-z]+-[0-9]+` pattern? (MEDIUM — no staleness tracking)
- **ADR reference** — does story reference at least one ADR? (check for `ADR-` pattern)
- **Status field** — present and readable?
- **Acceptance criteria** — does the story have a checkbox list (`- [ ]`)?
### 2e: Infrastructure Audit
| Artifact | Path | Impact if missing |
|---|---|---|
| TR registry | `docs/architecture/tr-registry.yaml` | HIGH — no stable requirement IDs |
| Control manifest | `docs/architecture/control-manifest.md` | HIGH — no layer rules for stories |
| Manifest version stamp | In manifest header: `Manifest Version:` | MEDIUM — staleness checks blind |
| Sprint status | `production/sprint-status.yaml` | MEDIUM — `/sprint-status` falls back to markdown |
| Stage file | `project.stage` in `project.yaml` (fallback `production/stage.txt`) | MEDIUM — phase auto-detect unreliable |
| Engine reference | `docs/engine-reference/[engine]/VERSION.md` | HIGH — ADR engine checks blind |
| Architecture traceability | `docs/architecture/requirements-traceability.md` | MEDIUM — no persistent matrix |
At `workflow: minimal` only the Engine reference row applies. The TR registry,
control manifest and its version stamp, sprint status, stage file and
traceability matrix are not on the minimal path, so their absence is not a gap.
### 2f: Project Config Audit
Read `project.yaml` (the primary config store) and `.claude/docs/technical-preferences.md` (legacy mirror). A setting counts as configured if EITHER source has a real value (in technical-preferences.md, `[TO BE CONFIGURED]` means unconfigured):
- `engine.name`/`version`/`language`/`rendering`/`physics` (else the Engine/Language/Rendering/Physics fields) → HIGH if unconfigured in both (ADR skills fail)
- `naming.*` (else Naming conventions) → MEDIUM
- `performance.*` (else Performance budgets) → MEDIUM
- Forbidden Patterns, Allowed Libraries (technical-preferences.md only — not migrated to project.yaml) → LOW (starts empty by design)
### 2g: v1.0 Migration Check
A project is a **v1.0 project needing migration** when `project.yaml` does NOT
exist at the repo root AND at least one legacy file does: `production/stage.txt`,
`production/review-mode.txt`, or a `.claude/docs/technical-preferences.md` with
real values.
"Real values" means one of the keys the converter actually migrates — Engine,
Language, Rendering, Physics, the naming, platform and performance fields,
Framework, or the specialists. Not merely "some bullet is filled in": the
shipped template ships one prose default (`- **Required Tests**: …`) that is
never migrated, and counting it made every fresh clone read as a v1.0 project.
Do not hand-migrate. Run the converter, which is deterministic and covered by
the framework's own test suite:
```bash
bash .claude/scripts/migrate-v1-config.sh --dry-run
```
The dry run writes nothing; record what it lists for the report. Do not run the
converter during the audit — Phase 2 reads silently. The migration is
classified BLOCKING in Phase 3, heads the plan, and **Phase 7 offers it as the
first action**: report what the dry run listed, then ask "May I run the
converter? It writes `project.yaml` and `production/migration-report.md`." If
the user approves, run it without `--dry-run`. It
writes `project.yaml` plus `production/migration-report.md` and **deletes
nothing** — the whole operation stays reversible with `git checkout`.
Then tell the user to read `production/migration-report.md` before running:
```bash
bash .claude/scripts/migrate-v1-config.sh --finalize
```
`--finalize` deletes a legacy file only after proving its value is present in
`project.yaml`; on mismatch it deletes nothing and exits 4. It never deletes
`technical-preferences.md`, which still holds Forbidden Patterns and Allowed
Libraries.
**If the script refuses with exit 3**, do not work around it. Exit 3 means one
of two things, and the message says which:
- **the values DISAGREE** — two sources of truth and no way to know which the
user edited last. Surface it and let them decide.
- **a `production/migration-report.md` is already present** — a migration ran
here, so these are post-migration leftovers and `--finalize` is the next step,
not a second `migrate`.
Both files merely *existing* is not exit 3 and must not be reported as a
conflict: `/start` writes `production/stage.txt` on every new v1.1 project as a
mirror, so agreement is the normal state. The script says
`the legacy files mirror it (values agree)` and exits 0 for that.
Classify as **BLOCKING** in Phase 3: until migration runs, every skill reads
config through the legacy fallback chain, and v1.1 settings are unavailable.
---
@@ -0,0 +1,29 @@
# /adopt — Phase 3: Classify and Prioritise Gaps
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 3: Classify and Prioritise Gaps
Organise every gap found across all audits into four severity tiers:
**BLOCKING** — Will cause template skills to silently produce wrong results *right now*.
Examples: ADR missing Status field, systems-index parenthetical status values,
engine not configured when ADRs exist.
**HIGH** — Will cause stories to be generated with missing safety checks, or
infrastructure bootstrapping will fail.
Examples: ADRs missing Engine Compatibility, GDDs missing Acceptance Criteria
(stories can't be generated from them), tr-registry.yaml missing.
**MEDIUM** — Degrades quality and pipeline tracking but does not break functionality.
Examples: GDDs missing Tuning Knobs or Formulas sections, stories missing TR-IDs,
sprint-status.yaml missing.
**LOW** — Retroactive improvements that are nice-to-have but not urgent.
Examples: Stories missing Manifest Version stamps, GDDs missing Open Questions section.
Count totals per tier. If zero BLOCKING and zero HIGH gaps: report that the project
is template-compatible and only advisory improvements remain.
---
@@ -0,0 +1,53 @@
# /adopt — Phase 4: Build the Migration Plan
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 4: Build the Migration Plan
Compose a numbered, ordered action plan. Ordering rules:
1. BLOCKING gaps first (must fix before any pipeline skill runs reliably)
2. HIGH gaps next, infrastructure before GDD/ADR content (bootstrapping needs correct formats)
3. MEDIUM gaps ordered: GDD gaps before ADR gaps before story gaps (stories depend on GDDs and ADRs)
4. LOW gaps last
For each gap, produce a plan entry with:
- A clear problem statement (one sentence, no jargon)
- The exact command to fix it, if a skill handles it
- Manual steps if it requires direct editing
- A time estimate (rough: 5 min / 30 min / 1 session)
- A checkbox `- [ ]` for tracking
**Special case — systems-index parenthetical status values:**
This is always the first item if present. Show the exact values that need changing
and the exact replacement text. Offer to fix this immediately before writing the plan.
**Special case — ADRs missing Status field:**
For each affected ADR, the fix is:
`/architecture-decision retrofit docs/architecture/adr-[NNNN]-[slug].md`
List each ADR as a separate checkable item.
**Special case — GDDs missing sections:**
For each affected GDD, list which sections are missing and the fix:
`/design-system retrofit design/gdd/[filename].md`
**Infrastructure bootstrap ordering** — always present in this sequence:
1. Fix ADR formats first (registry depends on reading ADR Status fields)
2. Run `/architecture-review` → bootstraps `tr-registry.yaml`
3. Run `/create-control-manifest` → creates manifest with version stamp
4. Run `/sprint-plan update` → creates `sprint-status.yaml`
5. Run `/gate-check [phase]` (the gate into the phase the project is in; at Concept there is none — Concept is the default stage, nothing to run) → writes `project.stage` in `project.yaml` (and legacy `stage.txt`) authoritatively
**At `workflow: minimal` the plan prescribes none of this sequence.** None of it
is on the minimal path: ADRs are not expected, the brief's build order is the
plan (no `/sprint-plan`), and nothing there runs `/gate-check`. The plan's
Step 3 says so in one line and names the path's next step instead —
`/create-stories` when no stories exist, else `/dev-story`.
**Existing stories** — note explicitly:
> "Existing stories continue to work with all template skills — all new format
> checks auto-pass when the fields are absent. They won't benefit from TR-ID
> staleness tracking or manifest version checks until they're regenerated. This
> is intentional: do not regenerate stories that are already in progress."
---
@@ -0,0 +1,48 @@
# /adopt — Phase 5: Present Summary and Ask to Write
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 5: Present Summary and Ask to Write
Present a compact summary before writing:
```
## Adoption Audit Summary
Phase detected: [phase]
Engine: [configured / NOT CONFIGURED]
GDDs audited: [N] ([X] fully compliant, [Y] with gaps)
ADRs audited: [N] ([X] fully compliant, [Y] with gaps)
Stories audited: [N]
Gap counts:
BLOCKING: [N] — template skills will malfunction without these fixes
HIGH: [N] — unsafe to run /create-stories or /story-readiness
MEDIUM: [N] — quality degradation
LOW: [N] — optional improvements
Estimated remediation: [X blocking items × ~Y min each = roughly Z hours]
```
Before asking to write, show a **Gap Preview**:
- List every BLOCKING gap as a one-line bullet describing the actual problem
(e.g. `systems-index.md: 3 rows have parenthetical status values`,
`adr-0002.md: missing ## Status section`). No counts — show the actual items.
- Show HIGH / MEDIUM / LOW as counts only (e.g. `HIGH: 4, MEDIUM: 2, LOW: 1`).
This gives the user enough context to judge scope before committing to writing the file.
If a prior adoption plan was detected in Phase 1, add a note:
> "A previous plan exists at `docs/adoption-plan-[prior-date].md`. The new plan will
> reflect current project state — it does not diff against the prior run."
Use `AskUserQuestion`:
- "Ready to write the migration plan?"
- "Yes — write `docs/adoption-plan-[date].md`"
- "Show me the full plan preview first (don't write yet)"
- "Cancel — I'll handle migration manually"
If the user picks "Show me the full plan preview", output the complete plan as a
fenced markdown block. Then ask again with the same three options.
---
+113
View File
@@ -0,0 +1,113 @@
# /adopt — Phases 6 and 6b: Write the Adoption Plan and Report Review Mode
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 6: Write the Adoption Plan
**In this file:**
- Phase 6: the adoption plan template, then the write
- Phase 6b: Report Review Mode
If approved, write `docs/adoption-plan-[date].md` with this structure:
```markdown
# Adoption Plan
> **Generated**: [date]
> **Project phase**: [phase]
> **Engine**: [name + version, or "Not configured"]
> **Template version**: v1.0+
Work through these steps in order. Check off each item as you complete it.
Re-run `/adopt` anytime to check remaining gaps.
---
## Step 1: Fix Blocking Gaps
[One sub-section per blocking gap with problem, fix command, time estimate, checkbox]
---
## Step 2: Fix High-Priority Gaps
[One sub-section per high gap]
---
## Step 3: Bootstrap Infrastructure
[At `workflow: minimal`, replace 3a–3d with one line: "Not on the minimal path —
the brief's build order is the plan. Next: `/create-stories` (or `/dev-story`
once stories exist)."]
### 3a. Register existing requirements (creates tr-registry.yaml)
Run `/architecture-review` — even if ADRs already exist, this run bootstraps
the TR registry from your existing GDDs and ADRs.
**Time**: 1 session (review can be long for large codebases)
- [ ] tr-registry.yaml created
### 3b. Create control manifest
Run `/create-control-manifest`
**Time**: 30 min
- [ ] docs/architecture/control-manifest.md created
### 3c. Create sprint tracking file
Run `/sprint-plan update`
**Time**: 5 min (if sprint plan already exists as markdown)
- [ ] production/sprint-status.yaml created
### 3d. Set authoritative project stage
Run `/gate-check [current-phase]` (the gate into the phase the project is in;
at Concept there is none — Concept is the default stage, nothing to run)
**Time**: 5 min
- [ ] `project.stage` in `project.yaml` written (legacy `production/stage.txt` also updated)
---
## Step 4: Medium-Priority Gaps
[One sub-section per medium gap]
---
## Step 5: Optional Improvements
[One sub-section per low gap]
---
## What to Expect from Existing Stories
Existing stories continue to work with all template skills. New format checks
(TR-ID validation, manifest version staleness) auto-pass when the fields are
absent — so nothing breaks. They won't benefit from staleness tracking until
regenerated. Do not regenerate stories that are in progress or done.
---
## Re-run
Run `/adopt` again after completing Step 3 to verify all blocking and high gaps
are resolved. The new run will reflect the current state of the project.
```
---
## Phase 6b: Report Review Mode
**Do not write a review mode.** `modes.review_mode` is one of the six knobs
`modes.rigor` fronts: pinning it in `project.yaml` shadows the rigor expansion, and
the legacy `production/review-mode.txt` sits *above* that expansion in resolution,
so either write would freeze director-review depth for good — the rule `/start`
and `project.yaml`'s header comment both state.
Report the value the bootstrap above resolved instead: "Review mode resolves to
`[value]` — from `modes.rigor`, unless something pins it." If the user wants a
different depth, point them to changing `modes.rigor`, or to pinning it on purpose
with `/settings --local modes.review_mode=<full|lean|solo>` (a personal override in
`project.local.yaml`).
---
@@ -0,0 +1,62 @@
# /adopt — Phase 7: Offer First Action
> Part of `/adopt`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 7: Offer First Action
After writing the plan, don't stop there. Pick the single highest-priority gap
and offer to handle it immediately using `AskUserQuestion`. Choose the first
branch that applies:
**If Phase 2g found a v1.0 project needing migration:** offer the converter run
described there — report what the dry run listed and ask "May I run the
converter? It writes `project.yaml` and `production/migration-report.md`."
Every other fix reads config through it, so it comes first.
**If there are parenthetical status values in systems-index.md:**
Use `AskUserQuestion`:
- "The most urgent fix is `systems-index.md` — [N] rows have parenthetical status
values (e.g. `Needs Revision (see notes)`) that break /gate-check,
/create-stories, and /architecture-review right now. I can fix these in-place."
- "Fix it now — edit systems-index.md"
- "I'll fix it myself"
- "Done — leave me with the plan"
**If ADRs are missing `## Status` (and no parenthetical issue):**
Use `AskUserQuestion`:
- "The most urgent fix is adding `## Status` to [N] ADR(s): [list filenames].
Without it, /story-readiness silently passes all ADR checks. Start with
[first affected filename]?"
- "Yes — retrofit [first affected filename] now"
- "Retrofit all [N] ADRs one by one"
- "I'll handle ADRs myself"
**If GDDs are missing Acceptance Criteria (and no blocking issues above):**
Use `AskUserQuestion`:
- "The most urgent gap is missing Acceptance Criteria in [N] GDD(s):
[list filenames]. Without them, /create-stories can't generate stories.
Start with [highest-priority GDD filename]?"
- "Yes — add Acceptance Criteria to [GDD filename] now"
- "Do all [N] GDDs one by one"
- "I'll handle GDDs myself"
**Otherwise, if any BLOCKING or HIGH gap remains** (one no branch above names —
e.g. a missing TR registry):
Use `AskUserQuestion`:
- "The most urgent remaining gap is [first BLOCKING or HIGH item in the plan] —
[one line on what it breaks]. Start on it now?"
- "Yes — start on [item]"
- "Show me that plan item first"
- "Done — leave me with the plan"
**If no BLOCKING or HIGH gaps exist:**
Use `AskUserQuestion`:
- "No blocking gaps — this project is template-compatible. What next?"
- "Walk me through the medium-priority improvements"
- "Run /project-stage-detect for a broader health check"
- "Done — I'll work through the plan at my own pace"
> **Adoption plan saved to `docs/adoption-plan-[date].md`.** Re-run `/adopt` at any time to re-check remaining gaps as you complete them.
---
+7 -535
View File
@@ -12,15 +12,14 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode`. No block →
defaults in `.claude/docs/config-resolution.md`.
# Architecture Decision
When this skill is invoked:
## 0. Parse Arguments — Detect Retrofit / Acceptance Mode
See `.claude/docs/director-gates.md` for the full check pattern. Individual gate definitions live in `.claude/docs/director-gates/[gate-id].md` — the spawned agent reads its own gate file; do not read it in the parent session.
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).
@@ -46,135 +45,12 @@ density.
- `minimal` — not required. Can still be run voluntarily.
**If the argument starts with `retrofit` followed by a file path**
(e.g., `/architecture-decision retrofit docs/architecture/adr-0001-event-system.md`):
Enter **retrofit mode**:
1. Read the existing ADR file completely.
2. Identify which template sections are present by scanning headings:
- `## Status` — **BLOCKING if missing**: `/story-readiness` cannot check ADR acceptance
- `## ADR Dependencies` — HIGH if missing: dependency ordering breaks
- `## Engine Compatibility` — HIGH if missing: post-cutoff risk unknown
- `## GDD Requirements Addressed` — MEDIUM if missing: traceability lost
- `## Date` — MEDIUM if missing, and no `## Last Verified` either: `/create-stories`
stamps stories with it and `/dev-story` compares against it, so without it a
story can never tell whether the ADR changed
3. Present to the user:
```
## Retrofit: [ADR title]
File: [path]
Sections already present (will not be touched):
✓ Status: [current value, or "MISSING — will add"]
✓ [section]
Missing sections to add:
✗ Status — BLOCKING (stories cannot validate ADR acceptance without this)
✗ ADR Dependencies — HIGH
✗ Engine Compatibility — HIGH
```
4. Ask: "Shall I add the [N] missing sections? I will not modify any existing content."
If no: write nothing, and report the missing sections by name.
5. If yes:
- For **Status**: ask the user — "What is the current status of this decision?"
Options: "Proposed", "Accepted", "Deprecated", "Superseded by ADR-XXXX"
An `Accepted` answer — a decision already in force — is not written as
given: write `Proposed`, add the other missing sections, then run
acceptance mode (below) on this ADR. Its dependency check, confirmation and
story unblocking apply here too; it stays the only path that sets `Accepted`.
- For **ADR Dependencies**: ask — "Does this decision depend on any other ADR?
Does it enable or block any other ADR or epic?" Accept "None" for each field.
- For **Engine Compatibility**: read the engine reference docs (same as Step 1 below)
and ask the user to confirm the domain. Then generate the table with verified data.
- For **GDD Requirements Addressed**: ask — "Which GDD systems motivated this decision?
What specific requirement in each GDD does this ADR address?"
- Append each missing section to the ADR file using the Edit tool.
- For **Date** (counted only when there is no `## Last Verified`): append
`## Date` with today's date — even when it is the only missing section, the
case `/dev-story` sends you here for — and say that it records the retrofit,
not when the decision was made.
- **Never modify any existing section.** Only append or fill absent sections.
6. Suggest: "Run `/architecture-review` to re-validate coverage now that this ADR
has its Status and Dependencies fields."
**Read `references/0-retrofit.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
**If the argument starts with `accept` followed by an ADR id**
(e.g., `/architecture-decision accept ADR-0005`):
Enter **acceptance mode**. This is the *only* path in the framework that moves an
ADR from `Proposed` to `Accepted`. Authoring always produces `Proposed`
(Step 5), while
`/create-control-manifest`, `/create-epics`, `/create-stories` and `/gate-check`
all require `Accepted` — so without this mode the pipeline had a state it could
enter and never leave.
1. **Resolve the id to a file, then read it.** Glob
`docs/architecture/adr-NNNN-*.md` for the given number. If **no** file matches,
or **more than one** does, stop and say which — do not pick one. If the file
has no `## Status` section, stop and say so; a missing Status is exactly what
retrofit mode is for.
2. **Check the current status.** If it is already `Accepted`, say so and stop.
If it is `Deprecated` or `Superseded`, refuse: reviving a superseded decision
is a new ADR, not a status edit.
3. **Check its dependencies first.** Read `## ADR Dependencies`.
**If that section is absent, empty, or reads `UNKNOWN`, do not read it as
"no dependencies" — refuse and say which:**
> "ADR-0005's dependency section is [absent / UNKNOWN], so I cannot tell what
> this decision rests on. An empty dependency list and an unexamined one look
> identical here, and only one of them is safe to accept. Run
> `/architecture-decision retrofit <path>` to establish it."
A dependency check reading a field that defaults to empty is the vacuous-pass
shape this gate exists to prevent — the check would examine nothing and report
clean.
If it depends on any ADR that is not itself `Accepted`, **refuse and name them**:
> "ADR-0005 depends on ADR-0002, which is still Proposed. Accept ADR-0002
> first — an accepted decision resting on an unaccepted one is not a decision,
> it is a deferral with a different label."
This is the same dependency rule `/architecture-review` already flags; here it
is enforced rather than reported.
4. **Confirm with the user, always.** Per `CONTRACT.md`, acceptance authority is
**the user, or `technical-director` on the user's explicit confirmation — no
other agent, and never this skill on its own.** Use `AskUserQuestion`:
- Prompt: "Accept ADR-NNNN — [title]? This is what unblocks stories and epics
that depend on it."
- Options: `[A] Yes — accept it` / `[B] Not yet — leave it Proposed`
**This prompt fires regardless of `modes.automation`, including `autonomous`.**
Acceptance is the decision the whole architecture pipeline gates on; it is not
a step to be inferred.
5. **Find the stories this will unblock, BEFORE the prompt in step 4.** Grep
every story for a Blocked Status line —
`Grep pattern="Status\**:\**\s*Blocked" path="production/epics" glob="**/story-*.md" output_mode="files_with_matches"`,
which matches `> **Status**: Blocked` (the form `/create-stories` writes),
`**Status:** Blocked` and `Status: Blocked` — and keep the files that name
this ADR's id as the reason they are blocked. That pairing is what "blocked
pending this ADR" means — a story blocked for an unrelated reason will not
name it. Leave out a story that names this ADR only as the successor to point
at (`point the story at ADR-NNNN`, the note for a `Deprecated` or
`Superseded` ADR): it is still governed by the old ADR, and accepting the
successor does not re-point it.
> **Stories live only under `production/epics/`.** A flat top-level stories
> directory does not exist and no skill creates one — never write or match a
> path outside `production/epics/`. `/dev-story` matches entries *by file
> path*, so a story recorded under any other path silently fails to match and
> never gets picked up.
Feed the count into step 4's prompt so it reads *"3 stories become Ready"*
rather than a generic claim: **the user is being asked to authorise an effect, and should be
shown the effect.** If none match, say "no stories are waiting on this" — that
is useful information, not an empty result to omit.
6. On confirmation, `Edit` the `## Status` line to `Accepted`. Leave an existing
`## Date` as it is: it records when the ADR was written, and `/create-stories`
stamps stories with it (or `## Last Verified`), so rewriting it on acceptance
would make every story drafted against the Proposed ADR look out of date to
`/dev-story`. **If that section is absent, add it** with today's date — retrofit
mode already owns this shape, and acceptance must not fail on a template that
predates the field.
7. Then set each story found in step 5 from `Blocked` to `Ready`. Unblocking is a
consequence of acceptance, never of authoring — see Step 6's note below.
8. Report what moved: the ADR (and its `## Date`, if one was added), and every
story that became Ready.
**Read `references/0-accept.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
If NOT in retrofit or acceptance mode, proceed to Step 1 below (normal ADR authoring).
@@ -190,47 +66,7 @@ Use the user's response as the title, then proceed to Step 1.
## 1. Load Engine Context (ALWAYS FIRST)
Before doing anything else, establish the engine environment:
1. Read `docs/engine-reference/[engine]/VERSION.md` to get:
- Engine name and version
- LLM knowledge cutoff date
- Post-cutoff version risk levels (LOW / MEDIUM / HIGH)
2. Identify the **domain** of this architecture decision from the title or
user description. Common domains: Physics, Rendering, UI, Audio, Navigation,
Animation, Networking, Core, Input, Scripting.
3. Read the corresponding module reference if it exists:
`docs/engine-reference/[engine]/modules/[domain].md`
4. Read `docs/engine-reference/[engine]/breaking-changes.md` — flag any
changes in the relevant domain that post-date the LLM's training cutoff.
5. Read `docs/engine-reference/[engine]/deprecated-apis.md` — flag any APIs
in the relevant domain that should not be used.
6. **Display a knowledge gap warning** before proceeding if the domain carries
MEDIUM or HIGH risk:
```
⚠️ ENGINE KNOWLEDGE GAP WARNING
Engine: [name + version]
Domain: [domain]
Risk Level: HIGH — This version is post-LLM-cutoff.
Key changes verified from engine-reference docs:
- [Change 1 relevant to this domain]
- [Change 2]
This ADR will be cross-referenced against the engine reference library.
Proceed with verified information only — do NOT rely solely on training data.
```
If no engine has been configured yet, prompt: "No engine is configured.
Run `/setup-engine` first, or tell me which engine you are using."
---
**Read `references/1-engine-context.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 2. Determine the next ADR number
@@ -240,379 +76,15 @@ Scan `docs/architecture/` for existing ADRs to find the next number.
## 3. Gather context
### 3a: Architecture Registry Check (BLOCKING gate) — do this FIRST
Read `docs/registry/architecture.yaml`. Extract entries relevant to this ADR's
domain and decision (grep by system name, domain keyword, or state being touched).
Run this before reading any existing ADR — the registry exists specifically so a
new ADR's author does not need to open prior ADRs to learn their binding facts
(state ownership, interface contracts, forbidden patterns).
Present any relevant stances to the user **before** the collaborative design
begins, as locked constraints:
```
## Existing Architectural Stances (must not contradict)
State Ownership:
player_health → owned by health-system (ADR-0001)
Interface: HealthComponent.current_health (read-only float)
→ If this ADR reads or writes player health, it must use this interface.
Interface Contracts:
damage_delivery → signal pattern (ADR-0003)
Signal: damage_dealt(amount, target, is_crit)
→ If this ADR delivers or receives damage events, it must use this signal.
Forbidden Patterns:
✗ autoload_singleton_coupling (ADR-0001)
✗ direct_cross_system_state_write (ADR-0000)
→ The proposed approach must not use these patterns.
```
If the user's proposed decision would contradict any registered stance, surface
the conflict immediately:
> "⚠️ Conflict: This ADR proposes [X], but ADR-[NNNN] established that [Y] is
> the accepted pattern for this purpose. Proceeding without resolving this will
> produce contradictory ADRs and inconsistent stories.
> Options: (1) Align with the existing stance, (2) Supersede ADR-[NNNN] with
> an explicit replacement, (3) Explain why this case is an exception."
Do not proceed to Step 4 (collaborative design) until any conflict is resolved
or explicitly accepted as an intentional exception.
### 3b: Existing ADRs and Related GDDs — registry-scoped, never unbounded
The registry (3a) covers *what* prior decisions bind — not always *why*. If the
registry surfaced a directly relevant ADR and its reasoning matters here (not
just its stated facts), read that specific ADR — never glob-and-read every
ADR in `docs/architecture/` on the chance one is relevant:
1. **Map its headings first** (cheap):
```
Grep pattern="^## " path="docs/architecture/[adr-file].md" output_mode="content" -n
```
2. **Under ~50KB** (`Bash: wc -c "docs/architecture/[adr-file].md"`) — one full
`Read` is fine; per-call overhead exceeds the savings from bounded reads at
this size.
3. **~50KB or larger** — bounded-read only `## Context`, `## Decision`, and
`## Consequences` (the sections that carry reasoning, not just facts) via
`Read(offset, limit)` from the heading map.
Read GDDs the same way `/design-system` Step 2b does: only GDDs the registry
or the ADR list names as directly relevant, and only their `## Dependencies`,
`## Formulas`, and `## Edge Cases` sections
(`Grep pattern="^## (Dependencies|Formulas|Edge Cases)" ... -A 40`) — never a
speculative full read of `design/gdd/*.md` looking for anything that might
relate.
Skip 3b entirely if the registry already answers everything this decision
needs — most ADRs will.
---
**Read `references/3-gather-context.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 4. Guide the decision collaboratively
Before asking anything, derive the skill's best guesses from the context already
gathered (GDDs read, engine reference loaded, existing ADRs scanned). Then present
a **confirm/adjust** prompt using `AskUserQuestion` — not open-ended questions.
**Derive assumptions first:**
- **Problem**: Infer from the title + GDD context what decision needs to be made
- **Alternatives**: Propose 2-3 concrete options from engine reference + GDD requirements
- **Dependencies**: Scan existing ADRs for upstream dependencies. **If the scan is
inconclusive, present `UNKNOWN — scan inconclusive, please confirm`, never
`None`.** The two are not interchangeable: `None` asserts that nothing upstream
constrains this decision, and a user confirming a prefilled list cannot tell an
assertion from a guess. This field is load-bearing — `/architecture-review`
flags unaccepted dependencies, `/dev-story` reads it, and the acceptance route
in Phase 0 **refuses to accept an ADR whose dependencies are not themselves
Accepted**. A dependency list that defaulted to empty makes that check pass
while examining nothing. `UNKNOWN` must be resolved during the confirm/adjust
prompt; it is a prompt state, never a value written to the file
- **GDD linkage**: Extract which GDD systems the title directly relates to
- **Status**: Always `Proposed` for new ADRs — never ask the user what the status is
**Scope of assumptions tab**: Assumptions cover only: problem framing, alternative approaches, upstream dependencies, GDD linkage, and status. Schema design questions (e.g., "How should spawn timing work?", "Should data be inline or external?") are NOT assumptions — they are design decisions belonging to a separate step after the assumptions are confirmed. Do not include schema design questions in the assumptions AskUserQuestion widget.
**After assumptions are confirmed**, if the ADR involves schema or data design choices, use a separate multi-tab `AskUserQuestion` to ask each design question independently before drafting.
**Present assumptions with `AskUserQuestion`:**
```
Here's what I'm assuming before drafting:
Problem: [one-sentence problem statement derived from context]
Alternatives I'll consider:
A) [option derived from engine reference]
B) [option derived from GDD requirements]
C) [option from common patterns]
GDD systems driving this: [list derived from context]
Dependencies: [upstream ADRs if any, otherwise "None"]
Status: Proposed
[A] Proceed — draft with these assumptions
[B] Change the alternatives list
[C] Adjust the GDD linkage
[D] Add a performance budget constraint
[E] Something else needs changing first
```
Do not generate the ADR until the user confirms assumptions or provides corrections.
**After engine specialist and TD reviews return** (Step 5.5/5.6), if unresolved
decisions remain, present each one as a separate `AskUserQuestion` with the proposed
options as choices plus a free-text escape:
```
Decision: [specific unresolved point]
[A] [option from specialist review]
[B] [alternative option]
[C] Different approach — I'll describe it
```
**ADR Dependencies** — derive from existing ADRs, then confirm:
- Does this decision depend on any other ADR not yet Accepted?
- Does it unlock or unblock any other ADR or epic?
- Does it block any specific epic from starting?
Record answers in the **ADR Dependencies** section. Write "None" for each field if no constraints apply.
---
**Read `references/4-decide.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 5. Generate the ADR
Following this format:
```markdown
# ADR-[NNNN]: [Title]
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXXX]
## Date
[Date of decision]
## Last Verified
[YYYY-MM-DD — when this ADR was last confirmed accurate against the current
engine version and design. Update this date when you re-read and confirm it is
still correct, even if nothing changed.]
## Decision Makers
[Who was involved in this decision]
## Summary
[2 sentences: what problem this ADR solves, and what was decided. Written for
tiered context loading — a skill scanning 20 ADRs uses this to decide whether to
read the full decision. Be specific: name the system, the problem, and the
chosen approach.]
## Engine Compatibility
| Field | Value |
|-------|-------|
| **Engine** | [e.g. Godot 4.6] |
| **Domain** | [Physics / Rendering / UI / Audio / Navigation / Animation / Networking / Core / Input] |
| **Knowledge Risk** | [LOW / MEDIUM / HIGH — from VERSION.md] |
| **References Consulted** | [List engine-reference docs read, e.g. `docs/engine-reference/godot/modules/physics.md`] |
| **Post-Cutoff APIs Used** | [Any APIs from post-LLM-cutoff versions this decision depends on, or "None"] |
| **Verification Required** | [Specific behaviours to test before shipping, or "None"] |
## ADR Dependencies
| Field | Value |
|-------|-------|
| **Depends On** | [ADR-NNNN (must be Accepted before this can be implemented), or "None"] |
| **Enables** | [ADR-NNNN (this ADR unlocks that decision), or "None"] |
| **Blocks** | [Epic/Story name — cannot start until this ADR is Accepted, or "None"] |
| **Ordering Note** | [Any sequencing constraint that isn't captured above] |
## Context
### Problem Statement
[What problem are we solving? Why does this decision need to be made now?]
### Constraints
- [Technical constraints]
- [Timeline constraints]
- [Resource constraints]
- [Compatibility requirements]
### Requirements
- [Must support X]
- [Must perform within Y budget]
- [Must integrate with Z]
## Decision
[The specific technical decision made, described in enough detail for someone
to implement it.]
### Architecture Diagram
[ASCII diagram or description of the system architecture this creates]
### Key Interfaces
[API contracts or interface definitions this decision creates]
### Implementation Guidelines
[Specific guidance for the programmer implementing this decision — the rules a
`/create-control-manifest` or `/dev-story` run should follow. State mandates as
"must / must never" so they extract cleanly.]
## Alternatives Considered
### Alternative 1: [Name]
- **Description**: [How this would work]
- **Pros**: [Advantages]
- **Cons**: [Disadvantages]
- **Rejection Reason**: [Why this was not chosen]
### Alternative 2: [Name]
- **Description**: [How this would work]
- **Pros**: [Advantages]
- **Cons**: [Disadvantages]
- **Rejection Reason**: [Why this was not chosen]
## Consequences
### Positive
- [Good outcomes of this decision]
### Negative
- [Trade-offs and costs accepted]
## Risks
- [Things that could go wrong]
- [Mitigation for each risk]
## GDD Requirements Addressed
| GDD System | Requirement | How This ADR Addresses It |
|------------|-------------|--------------------------|
| [system-name].md | [specific rule, formula, or performance constraint from that GDD] | [how this decision satisfies it] |
## Performance Implications
- **CPU**: [Expected impact]
- **Memory**: [Expected impact]
- **Load Time**: [Expected impact]
- **Network**: [Expected impact, if applicable]
## Migration Plan
[If this changes existing code, how do we get from here to there?]
## Validation Criteria
[How will we know this decision was correct? What metrics or tests?]
## Related
- [Links to related ADRs — note if supersedes, contradicts, or depends on]
- [Links to related design documents]
```
5.5. **Engine Specialist Validation** — Before saving, spawn the **primary engine specialist** via `Agent` to validate the drafted ADR:
- Resolve the primary specialist: `<engine>-specialist` derived from `engine.name` in `project.yaml` (Godot→`godot-specialist`, Unity→`unity-specialist`, Unreal→`unreal-specialist`); if `engine.name` is absent or empty, read the Primary line of the `## Engine Specialists` section in `.claude/docs/technical-preferences.md`
- If no engine is configured (neither source yields an engine), skip this step **Record ``Engine validation: NOT ASSESSED — no engine configured (`engine.name` unset in `project.yaml`)`` in this run's output.** A skipped check that says nothing is indistinguishable from a check that passed; the reader cannot tell engine guidance was never sought.
- Spawn `subagent_type: [primary specialist]` with: the ADR's Engine Compatibility section, Decision section, Key Interfaces, and the engine reference docs path. Ask them to:
1. Confirm the proposed approach is idiomatic for the pinned engine version
2. Flag any APIs or patterns that are deprecated or changed post-training-cutoff
3. Identify engine-specific risks or gotchas not captured in the current ADR draft
- If the specialist identifies a **blocking issue** (wrong API, deprecated approach, engine version incompatibility): revise the Decision and Engine Compatibility sections accordingly, then confirm the changes with the user before proceeding
- If the specialist finds **minor notes** only: incorporate them into the ADR's Risks subsection
**Review mode check** — apply before spawning TD-ADR:
- `solo` → skip. Note: "TD-ADR skipped — Solo mode." Proceed to Step 5.7 (GDD sync check).
- `lean` → skip (not a PHASE-GATE). Note: "TD-ADR skipped — Lean mode." Proceed to Step 5.7 (GDD sync check).
- `full` → spawn as normal.
5.6. **Technical Director Strategic Review** — After the engine specialist validation, spawn `technical-director` via `Agent` using gate **TD-ADR** (`.claude/docs/director-gates/td-adr.md`):
- Pass: the ADR file path (or draft content), engine version, domain, any existing ADRs in the same domain
- The TD validates architectural coherence (is this decision consistent with the whole system?) — distinct from the engine specialist's API-level check
- On CONCERNS: show them to the user verbatim and ask with the standard options from `director-gates.md` — `Revise flagged items` / `Accept and proceed` / `Discuss further`. Revise the flagged Decision or Alternatives sections only on `Revise flagged items`.
- On REJECT: show the blockers verbatim and revise the Decision or Alternatives sections before proceeding.
- A revised draft still reaches the user through the write approval below; nothing is written before it. A `NOT ASSESSED` answer is not an approval — name the missing input (`director-gates.md`).
5.7. **GDD Sync Check** — Before presenting the write approval, scan all GDDs
referenced in the "GDD Requirements Addressed" section for naming inconsistencies
with the ADR's Key Interfaces and Decision sections (renamed signals, API methods,
or data types). If any are found, surface them as a **prominent warning block**
immediately before the write approval — not as a footnote:
```
⚠️ GDD SYNC REQUIRED
[gdd-filename].md uses names this ADR has renamed:
[old_name] → [new_name_from_adr]
[old_name_2] → [new_name_2_from_adr]
The GDD must be updated before or alongside writing this ADR to prevent
developers reading the GDD from implementing the wrong interface.
```
**This check has three outcomes, not two.** The two above are "found" and "none
found"; the third is **could not check**, and until now it fell through the
silent branch and rendered exactly like a clean result.
- **None found** — print one line, do not stay silent:
`GDD sync: checked [N] referenced GDD(s), no naming inconsistencies.`
A silent pass is indistinguishable from a check that never ran, and this one
guards against developers implementing the wrong interface from a stale GDD.
- **Could not check** — the ADR has no `GDD Requirements Addressed` section, it
names no GDDs, or a named GDD does not exist on disk. Print:
`GDD sync: NOT ASSESSED — [which reason, and which files]`
Do **not** treat an ADR that references no GDDs as one whose GDDs are
consistent. Nothing was compared.
Only the warning block itself is conditional; the check always reports.
5. **Write approval** — Use `AskUserQuestion`:
If GDD sync issues were found:
- "ADR draft is complete. How would you like to proceed?"
- [A] Write ADR + update GDD in the same pass
- [B] Write ADR only — I'll update the GDD manually
- [C] Not yet — I need to review further
If no GDD sync issues:
- "ADR draft is complete. May I write it?"
- [A] Write ADR to `docs/architecture/adr-[NNNN]-[slug].md`
- [B] Not yet — I need to review further
If yes to any write option, write the file, creating the directory if needed.
For option [A] with GDD update: also update the GDD file(s) to use the new names.
6. **Update Architecture Registry**
Scan the written ADR for new architectural stances that should be registered:
- State it claims ownership of
- Interface contracts it defines (signal signatures, method APIs)
- Performance budget it claims
- API choices it makes explicitly
- Patterns it bans (Consequences → Negative or explicit "do not use X")
Present candidates:
```
Registry candidates from this ADR:
NEW state ownership: player_stamina → stamina-system
NEW interface contract: stamina_depleted signal
NEW performance budget: stamina-system: 0.5ms/frame
NEW forbidden pattern: polling stamina each frame (use signal instead)
EXISTING (referenced_by update only): player_health → already registered ✅
```
**Registry append logic**: When writing to `docs/registry/architecture.yaml`, do NOT assume sections are empty. The file may already have entries from previous ADRs written in this session. Before each Edit call:
1. Read the current state of `docs/registry/architecture.yaml`
2. Find the correct section (state_ownership, interfaces, forbidden_patterns, api_decisions)
3. Append the new entry AFTER the last existing entry in that section — do not try to replace a `[]` placeholder that may no longer exist
4. If the section has entries already, use the closing content of the last entry as the `old_string` anchor, and append the new entry after it
**BLOCKING — do not write to `docs/registry/architecture.yaml` without explicit user approval.**
Ask using `AskUserQuestion`:
- "May I update `docs/registry/architecture.yaml` with these [N] new stances?"
- Options: "Yes — update the registry", "Not yet — I want to review the candidates", "Skip registry update"
Only proceed if the user selects yes. If yes: append new entries. Never modify existing entries — if a stance is
changing, set the old entry to `status: superseded_by: ADR-[NNNN]` and add the new entry.
---
**Read `references/5-generate.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 6. Closing Next Steps
@@ -0,0 +1,84 @@
# /architecture-decision — Acceptance Mode
> Part of `/architecture-decision`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
**If the argument starts with `accept` followed by an ADR id**
(e.g., `/architecture-decision accept ADR-0005`):
Enter **acceptance mode**. This is the *only* path in the framework that moves an
ADR from `Proposed` to `Accepted`. Authoring always produces `Proposed`
(Step 5), while
`/create-control-manifest`, `/create-epics`, `/create-stories` and `/gate-check`
all require `Accepted` — so without this mode the pipeline had a state it could
enter and never leave.
1. **Resolve the id to a file, then read it.** Glob
`docs/architecture/adr-NNNN-*.md` for the given number. If **no** file matches,
or **more than one** does, stop and say which — do not pick one. If the file
has no `## Status` section, stop and say so; a missing Status is exactly what
retrofit mode is for.
2. **Check the current status.** If it is already `Accepted`, say so and stop.
If it is `Deprecated` or `Superseded`, refuse: reviving a superseded decision
is a new ADR, not a status edit.
3. **Check its dependencies first.** Read `## ADR Dependencies`.
**If that section is absent, empty, or reads `UNKNOWN`, do not read it as
"no dependencies" — refuse and say which:**
> "ADR-0005's dependency section is [absent / UNKNOWN], so I cannot tell what
> this decision rests on. An empty dependency list and an unexamined one look
> identical here, and only one of them is safe to accept. Run
> `/architecture-decision retrofit <path>` to establish it."
A dependency check reading a field that defaults to empty is the vacuous-pass
shape this gate exists to prevent — the check would examine nothing and report
clean.
If it depends on any ADR that is not itself `Accepted`, **refuse and name them**:
> "ADR-0005 depends on ADR-0002, which is still Proposed. Accept ADR-0002
> first — an accepted decision resting on an unaccepted one is not a decision,
> it is a deferral with a different label."
This is the same dependency rule `/architecture-review` already flags; here it
is enforced rather than reported.
4. **Confirm with the user, always.** Per `CONTRACT.md`, acceptance authority is
**the user, or `technical-director` on the user's explicit confirmation — no
other agent, and never this skill on its own.** Use `AskUserQuestion`:
- Prompt: "Accept ADR-NNNN — [title]? This is what unblocks stories and epics
that depend on it."
- Options: `[A] Yes — accept it` / `[B] Not yet — leave it Proposed`
**This prompt fires regardless of `modes.automation`, including `autonomous`.**
Acceptance is the decision the whole architecture pipeline gates on; it is not
a step to be inferred.
5. **Find the stories this will unblock, BEFORE the prompt in step 4.** Grep
every story for a Blocked Status line —
`Grep pattern="Status\**:\**\s*Blocked" path="production/epics" glob="**/story-*.md" output_mode="files_with_matches"`,
which matches `> **Status**: Blocked` (the form `/create-stories` writes),
`**Status:** Blocked` and `Status: Blocked` — and keep the files that name
this ADR's id as the reason they are blocked. That pairing is what "blocked
pending this ADR" means — a story blocked for an unrelated reason will not
name it. Leave out a story that names this ADR only as the successor to point
at (`point the story at ADR-NNNN`, the note for a `Deprecated` or
`Superseded` ADR): it is still governed by the old ADR, and accepting the
successor does not re-point it.
> **Stories live only under `production/epics/`.** A flat top-level stories
> directory does not exist and no skill creates one — never write or match a
> path outside `production/epics/`. `/dev-story` matches entries *by file
> path*, so a story recorded under any other path silently fails to match and
> never gets picked up.
Feed the count into step 4's prompt so it reads *"3 stories become Ready"*
rather than a generic claim: **the user is being asked to authorise an effect, and should be
shown the effect.** If none match, say "no stories are waiting on this" — that
is useful information, not an empty result to omit.
6. On confirmation, `Edit` the `## Status` line to `Accepted`. Leave an existing
`## Date` as it is: it records when the ADR was written, and `/create-stories`
stamps stories with it (or `## Last Verified`), so rewriting it on acceptance
would make every story drafted against the Proposed ADR look out of date to
`/dev-story`. **If that section is absent, add it** with today's date — retrofit
mode already owns this shape, and acceptance must not fail on a template that
predates the field.
7. Then set each story found in step 5 from `Blocked` to `Ready`. Unblocking is a
consequence of acceptance, never of authoring — see Step 6's note below.
8. Report what moved: the ADR (and its `## Date`, if one was added), and every
story that became Ready.
@@ -0,0 +1,57 @@
# /architecture-decision — Retrofit Mode
> Part of `/architecture-decision`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
**If the argument starts with `retrofit` followed by a file path**
(e.g., `/architecture-decision retrofit docs/architecture/adr-0001-event-system.md`):
Enter **retrofit mode**:
1. Read the existing ADR file completely.
2. Identify which template sections are present by scanning headings:
- `## Status` — **BLOCKING if missing**: `/story-readiness` cannot check ADR acceptance
- `## ADR Dependencies` — HIGH if missing: dependency ordering breaks
- `## Engine Compatibility` — HIGH if missing: post-cutoff risk unknown
- `## GDD Requirements Addressed` — MEDIUM if missing: traceability lost
- `## Date` — MEDIUM if missing, and no `## Last Verified` either: `/create-stories`
stamps stories with it and `/dev-story` compares against it, so without it a
story can never tell whether the ADR changed
3. Present to the user:
```
## Retrofit: [ADR title]
File: [path]
Sections already present (will not be touched):
✓ Status: [current value, or "MISSING — will add"]
✓ [section]
Missing sections to add:
✗ Status — BLOCKING (stories cannot validate ADR acceptance without this)
✗ ADR Dependencies — HIGH
✗ Engine Compatibility — HIGH
```
4. Ask: "Shall I add the [N] missing sections? I will not modify any existing content."
If no: write nothing, and report the missing sections by name.
5. If yes:
- For **Status**: ask the user — "What is the current status of this decision?"
Options: "Proposed", "Accepted", "Deprecated", "Superseded by ADR-XXXX"
An `Accepted` answer — a decision already in force — is not written as
given: write `Proposed`, add the other missing sections, then run
acceptance mode (below) on this ADR. Its dependency check, confirmation and
story unblocking apply here too; it stays the only path that sets `Accepted`.
- For **ADR Dependencies**: ask — "Does this decision depend on any other ADR?
Does it enable or block any other ADR or epic?" Accept "None" for each field.
- For **Engine Compatibility**: read the engine reference docs (same as Step 1 below)
and ask the user to confirm the domain. Then generate the table with verified data.
- For **GDD Requirements Addressed**: ask — "Which GDD systems motivated this decision?
What specific requirement in each GDD does this ADR address?"
- Append each missing section to the ADR file using the Edit tool.
- For **Date** (counted only when there is no `## Last Verified`): append
`## Date` with today's date — even when it is the only missing section, the
case `/dev-story` sends you here for — and say that it records the retrofit,
not when the decision was made.
- **Never modify any existing section.** Only append or fill absent sections.
6. Suggest: "Run `/architecture-review` to re-validate coverage now that this ADR
has its Status and Dependencies fields."
@@ -0,0 +1,48 @@
# /architecture-decision — Step 1: Load Engine Context
> Part of `/architecture-decision`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 1. Load Engine Context (ALWAYS FIRST)
Before doing anything else, establish the engine environment:
1. Read `docs/engine-reference/[engine]/VERSION.md` to get:
- Engine name and version
- LLM knowledge cutoff date
- Post-cutoff version risk levels (LOW / MEDIUM / HIGH)
2. Identify the **domain** of this architecture decision from the title or
user description. Common domains: Physics, Rendering, UI, Audio, Navigation,
Animation, Networking, Core, Input, Scripting.
3. Read the corresponding module reference if it exists:
`docs/engine-reference/[engine]/modules/[domain].md`
4. Read `docs/engine-reference/[engine]/breaking-changes.md` — flag any
changes in the relevant domain that post-date the LLM's training cutoff.
5. Read `docs/engine-reference/[engine]/deprecated-apis.md` — flag any APIs
in the relevant domain that should not be used.
6. **Display a knowledge gap warning** before proceeding if the domain carries
MEDIUM or HIGH risk:
```
⚠️ ENGINE KNOWLEDGE GAP WARNING
Engine: [name + version]
Domain: [domain]
Risk Level: HIGH — This version is post-LLM-cutoff.
Key changes verified from engine-reference docs:
- [Change 1 relevant to this domain]
- [Change 2]
This ADR will be cross-referenced against the engine reference library.
Proceed with verified information only — do NOT rely solely on training data.
```
If no engine has been configured yet, prompt: "No engine is configured.
Run `/setup-engine` first, or tell me which engine you are using."
---
@@ -0,0 +1,78 @@
# /architecture-decision — Steps 3a and 3b: Gather Context
> Part of `/architecture-decision`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 3. Gather context
### 3a: Architecture Registry Check (BLOCKING gate) — do this FIRST
Read `docs/registry/architecture.yaml`. Extract entries relevant to this ADR's
domain and decision (grep by system name, domain keyword, or state being touched).
Run this before reading any existing ADR — the registry exists specifically so a
new ADR's author does not need to open prior ADRs to learn their binding facts
(state ownership, interface contracts, forbidden patterns).
Present any relevant stances to the user **before** the collaborative design
begins, as locked constraints:
```
## Existing Architectural Stances (must not contradict)
State Ownership:
player_health → owned by health-system (ADR-0001)
Interface: HealthComponent.current_health (read-only float)
→ If this ADR reads or writes player health, it must use this interface.
Interface Contracts:
damage_delivery → signal pattern (ADR-0003)
Signal: damage_dealt(amount, target, is_crit)
→ If this ADR delivers or receives damage events, it must use this signal.
Forbidden Patterns:
✗ autoload_singleton_coupling (ADR-0001)
✗ direct_cross_system_state_write (ADR-0000)
→ The proposed approach must not use these patterns.
```
If the user's proposed decision would contradict any registered stance, surface
the conflict immediately:
> "⚠️ Conflict: This ADR proposes [X], but ADR-[NNNN] established that [Y] is
> the accepted pattern for this purpose. Proceeding without resolving this will
> produce contradictory ADRs and inconsistent stories.
> Options: (1) Align with the existing stance, (2) Supersede ADR-[NNNN] with
> an explicit replacement, (3) Explain why this case is an exception."
Do not proceed to Step 4 (collaborative design) until any conflict is resolved
or explicitly accepted as an intentional exception.
### 3b: Existing ADRs and Related GDDs — registry-scoped, never unbounded
The registry (3a) covers *what* prior decisions bind — not always *why*. If the
registry surfaced a directly relevant ADR and its reasoning matters here (not
just its stated facts), read that specific ADR — never glob-and-read every
ADR in `docs/architecture/` on the chance one is relevant:
1. **Map its headings first** (cheap):
```
Grep pattern="^## " path="docs/architecture/[adr-file].md" output_mode="content" -n
```
2. **Under ~50KB** (`Bash: wc -c "docs/architecture/[adr-file].md"`) — one full
`Read` is fine; per-call overhead exceeds the savings from bounded reads at
this size.
3. **~50KB or larger** — bounded-read only `## Context`, `## Decision`, and
`## Consequences` (the sections that carry reasoning, not just facts) via
`Read(offset, limit)` from the heading map.
Read GDDs the same way `/design-system` Step 2b does: only GDDs the registry
or the ADR list names as directly relevant, and only their `## Dependencies`,
`## Formulas`, and `## Edge Cases` sections
(`Grep pattern="^## (Dependencies|Formulas|Edge Cases)" ... -A 40`) — never a
speculative full read of `design/gdd/*.md` looking for anything that might
relate.
Skip 3b entirely if the registry already answers everything this decision
needs — most ADRs will.
---
@@ -0,0 +1,73 @@
# /architecture-decision — Step 4: Guide the Decision Collaboratively
> Part of `/architecture-decision`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 4. Guide the decision collaboratively
Before asking anything, derive the skill's best guesses from the context already
gathered (GDDs read, engine reference loaded, existing ADRs scanned). Then present
a **confirm/adjust** prompt using `AskUserQuestion` — not open-ended questions.
**Derive assumptions first:**
- **Problem**: Infer from the title + GDD context what decision needs to be made
- **Alternatives**: Propose 2-3 concrete options from engine reference + GDD requirements
- **Dependencies**: Scan existing ADRs for upstream dependencies. **If the scan is
inconclusive, present `UNKNOWN — scan inconclusive, please confirm`, never
`None`.** The two are not interchangeable: `None` asserts that nothing upstream
constrains this decision, and a user confirming a prefilled list cannot tell an
assertion from a guess. This field is load-bearing — `/architecture-review`
flags unaccepted dependencies, `/dev-story` reads it, and the acceptance route
in Phase 0 **refuses to accept an ADR whose dependencies are not themselves
Accepted**. A dependency list that defaulted to empty makes that check pass
while examining nothing. `UNKNOWN` must be resolved during the confirm/adjust
prompt; it is a prompt state, never a value written to the file
- **GDD linkage**: Extract which GDD systems the title directly relates to
- **Status**: Always `Proposed` for new ADRs — never ask the user what the status is
**Scope of assumptions tab**: Assumptions cover only: problem framing, alternative approaches, upstream dependencies, GDD linkage, and status. Schema design questions (e.g., "How should spawn timing work?", "Should data be inline or external?") are NOT assumptions — they are design decisions belonging to a separate step after the assumptions are confirmed. Do not include schema design questions in the assumptions AskUserQuestion widget.
**After assumptions are confirmed**, if the ADR involves schema or data design choices, use a separate multi-tab `AskUserQuestion` to ask each design question independently before drafting.
**Present assumptions with `AskUserQuestion`:**
```
Here's what I'm assuming before drafting:
Problem: [one-sentence problem statement derived from context]
Alternatives I'll consider:
A) [option derived from engine reference]
B) [option derived from GDD requirements]
C) [option from common patterns]
GDD systems driving this: [list derived from context]
Dependencies: [upstream ADRs if any, otherwise "None"]
Status: Proposed
[A] Proceed — draft with these assumptions
[B] Change the alternatives list
[C] Adjust the GDD linkage
[D] Add a performance budget constraint
[E] Something else needs changing first
```
Do not generate the ADR until the user confirms assumptions or provides corrections.
**After engine specialist and TD reviews return** (Step 5.5/5.6), if unresolved
decisions remain, present each one as a separate `AskUserQuestion` with the proposed
options as choices plus a free-text escape:
```
Decision: [specific unresolved point]
[A] [option from specialist review]
[B] [alternative option]
[C] Different approach — I'll describe it
```
**ADR Dependencies** — derive from existing ADRs, then confirm:
- Does this decision depend on any other ADR not yet Accepted?
- Does it unlock or unblock any other ADR or epic?
- Does it block any specific epic from starting?
Record answers in the **ADR Dependencies** section. Write "None" for each field if no constraints apply.
---
@@ -0,0 +1,246 @@
# /architecture-decision — Step 5: Generate the ADR
> Part of `/architecture-decision`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 5. Generate the ADR
**In this file:**
- The ADR template
- 5.5 Engine Specialist Validation
- 5.6 Technical Director Strategic Review, with the review mode check
- 5.7 GDD Sync Check: found, none found, could not check
- Write approval
- Update Architecture Registry, and the registry append logic
Following this format:
```markdown
# ADR-[NNNN]: [Title]
## Status
[Proposed | Accepted | Deprecated | Superseded by ADR-XXXX]
## Date
[Date of decision]
## Last Verified
[YYYY-MM-DD — when this ADR was last confirmed accurate against the current
engine version and design. Update this date when you re-read and confirm it is
still correct, even if nothing changed.]
## Decision Makers
[Who was involved in this decision]
## Summary
[2 sentences: what problem this ADR solves, and what was decided. Written for
tiered context loading — a skill scanning 20 ADRs uses this to decide whether to
read the full decision. Be specific: name the system, the problem, and the
chosen approach.]
## Engine Compatibility
| Field | Value |
|-------|-------|
| **Engine** | [e.g. Godot 4.6] |
| **Domain** | [Physics / Rendering / UI / Audio / Navigation / Animation / Networking / Core / Input] |
| **Knowledge Risk** | [LOW / MEDIUM / HIGH — from VERSION.md] |
| **References Consulted** | [List engine-reference docs read, e.g. `docs/engine-reference/godot/modules/physics.md`] |
| **Post-Cutoff APIs Used** | [Any APIs from post-LLM-cutoff versions this decision depends on, or "None"] |
| **Verification Required** | [Specific behaviours to test before shipping, or "None"] |
## ADR Dependencies
| Field | Value |
|-------|-------|
| **Depends On** | [ADR-NNNN (must be Accepted before this can be implemented), or "None"] |
| **Enables** | [ADR-NNNN (this ADR unlocks that decision), or "None"] |
| **Blocks** | [Epic/Story name — cannot start until this ADR is Accepted, or "None"] |
| **Ordering Note** | [Any sequencing constraint that isn't captured above] |
## Context
### Problem Statement
[What problem are we solving? Why does this decision need to be made now?]
### Constraints
- [Technical constraints]
- [Timeline constraints]
- [Resource constraints]
- [Compatibility requirements]
### Requirements
- [Must support X]
- [Must perform within Y budget]
- [Must integrate with Z]
## Decision
[The specific technical decision made, described in enough detail for someone
to implement it.]
### Architecture Diagram
[ASCII diagram or description of the system architecture this creates]
### Key Interfaces
[API contracts or interface definitions this decision creates]
### Implementation Guidelines
[Specific guidance for the programmer implementing this decision — the rules a
`/create-control-manifest` or `/dev-story` run should follow. State mandates as
"must / must never" so they extract cleanly.]
## Alternatives Considered
### Alternative 1: [Name]
- **Description**: [How this would work]
- **Pros**: [Advantages]
- **Cons**: [Disadvantages]
- **Rejection Reason**: [Why this was not chosen]
### Alternative 2: [Name]
- **Description**: [How this would work]
- **Pros**: [Advantages]
- **Cons**: [Disadvantages]
- **Rejection Reason**: [Why this was not chosen]
## Consequences
### Positive
- [Good outcomes of this decision]
### Negative
- [Trade-offs and costs accepted]
## Risks
- [Things that could go wrong]
- [Mitigation for each risk]
## GDD Requirements Addressed
| GDD System | Requirement | How This ADR Addresses It |
|------------|-------------|--------------------------|
| [system-name].md | [specific rule, formula, or performance constraint from that GDD] | [how this decision satisfies it] |
## Performance Implications
- **CPU**: [Expected impact]
- **Memory**: [Expected impact]
- **Load Time**: [Expected impact]
- **Network**: [Expected impact, if applicable]
## Migration Plan
[If this changes existing code, how do we get from here to there?]
## Validation Criteria
[How will we know this decision was correct? What metrics or tests?]
## Related
- [Links to related ADRs — note if supersedes, contradicts, or depends on]
- [Links to related design documents]
```
5.5. **Engine Specialist Validation** — Before saving, spawn the **primary engine specialist** via `Agent` to validate the drafted ADR:
- Resolve the primary specialist: `<engine>-specialist` derived from `engine.name` in `project.yaml` (Godot→`godot-specialist`, Unity→`unity-specialist`, Unreal→`unreal-specialist`); if `engine.name` is absent or empty, read the Primary line of the `## Engine Specialists` section in `.claude/docs/technical-preferences.md`
- If no engine is configured (neither source yields an engine), skip this step **Record ``Engine validation: NOT ASSESSED — no engine configured (`engine.name` unset in `project.yaml`)`` in this run's output.** A skipped check that says nothing is indistinguishable from a check that passed; the reader cannot tell engine guidance was never sought.
- Spawn `subagent_type: [primary specialist]` with: the ADR's Engine Compatibility section, Decision section, Key Interfaces, and the engine reference docs path. Ask them to:
1. Confirm the proposed approach is idiomatic for the pinned engine version
2. Flag any APIs or patterns that are deprecated or changed post-training-cutoff
3. Identify engine-specific risks or gotchas not captured in the current ADR draft
- If the specialist identifies a **blocking issue** (wrong API, deprecated approach, engine version incompatibility): revise the Decision and Engine Compatibility sections accordingly, then confirm the changes with the user before proceeding
- If the specialist finds **minor notes** only: incorporate them into the ADR's Risks subsection
**Review mode check** — apply before spawning TD-ADR:
- `solo` → skip. Note: "TD-ADR skipped — Solo mode." Proceed to Step 5.7 (GDD sync check).
- `lean` → skip (not a PHASE-GATE). Note: "TD-ADR skipped — Lean mode." Proceed to Step 5.7 (GDD sync check).
- `full` → spawn as normal.
5.6. **Technical Director Strategic Review** — After the engine specialist validation, spawn `technical-director` via `Agent` using gate **TD-ADR** (`.claude/docs/director-gates/td-adr.md`):
- Pass: the ADR file path (or draft content), engine version, domain, any existing ADRs in the same domain
- The TD validates architectural coherence (is this decision consistent with the whole system?) — distinct from the engine specialist's API-level check
- On CONCERNS: show them to the user verbatim and ask with the standard options from `director-gates.md` — `Revise flagged items` / `Accept and proceed` / `Discuss further`. Revise the flagged Decision or Alternatives sections only on `Revise flagged items`.
- On REJECT: show the blockers verbatim and revise the Decision or Alternatives sections before proceeding.
- A revised draft still reaches the user through the write approval below; nothing is written before it. A `NOT ASSESSED` answer is not an approval — name the missing input (`director-gates.md`).
5.7. **GDD Sync Check** — Before presenting the write approval, scan all GDDs
referenced in the "GDD Requirements Addressed" section for naming inconsistencies
with the ADR's Key Interfaces and Decision sections (renamed signals, API methods,
or data types). If any are found, surface them as a **prominent warning block**
immediately before the write approval — not as a footnote:
```
⚠️ GDD SYNC REQUIRED
[gdd-filename].md uses names this ADR has renamed:
[old_name] → [new_name_from_adr]
[old_name_2] → [new_name_2_from_adr]
The GDD must be updated before or alongside writing this ADR to prevent
developers reading the GDD from implementing the wrong interface.
```
**This check has three outcomes, not two.** The two above are "found" and "none
found"; the third is **could not check**, and until now it fell through the
silent branch and rendered exactly like a clean result.
- **None found** — print one line, do not stay silent:
`GDD sync: checked [N] referenced GDD(s), no naming inconsistencies.`
A silent pass is indistinguishable from a check that never ran, and this one
guards against developers implementing the wrong interface from a stale GDD.
- **Could not check** — the ADR has no `GDD Requirements Addressed` section, it
names no GDDs, or a named GDD does not exist on disk. Print:
`GDD sync: NOT ASSESSED — [which reason, and which files]`
Do **not** treat an ADR that references no GDDs as one whose GDDs are
consistent. Nothing was compared.
Only the warning block itself is conditional; the check always reports.
5. **Write approval** — Use `AskUserQuestion`:
If GDD sync issues were found:
- "ADR draft is complete. How would you like to proceed?"
- [A] Write ADR + update GDD in the same pass
- [B] Write ADR only — I'll update the GDD manually
- [C] Not yet — I need to review further
If no GDD sync issues:
- "ADR draft is complete. May I write it?"
- [A] Write ADR to `docs/architecture/adr-[NNNN]-[slug].md`
- [B] Not yet — I need to review further
If yes to any write option, write the file, creating the directory if needed.
For option [A] with GDD update: also update the GDD file(s) to use the new names.
6. **Update Architecture Registry**
Scan the written ADR for new architectural stances that should be registered:
- State it claims ownership of
- Interface contracts it defines (signal signatures, method APIs)
- Performance budget it claims
- API choices it makes explicitly
- Patterns it bans (Consequences → Negative or explicit "do not use X")
Present candidates:
```
Registry candidates from this ADR:
NEW state ownership: player_stamina → stamina-system
NEW interface contract: stamina_depleted signal
NEW performance budget: stamina-system: 0.5ms/frame
NEW forbidden pattern: polling stamina each frame (use signal instead)
EXISTING (referenced_by update only): player_health → already registered ✅
```
**Registry append logic**: When writing to `docs/registry/architecture.yaml`, do NOT assume sections are empty. The file may already have entries from previous ADRs written in this session. Before each Edit call:
1. Read the current state of `docs/registry/architecture.yaml`
2. Find the correct section (state_ownership, interfaces, forbidden_patterns, api_decisions)
3. Append the new entry AFTER the last existing entry in that section — do not try to replace a `[]` placeholder that may no longer exist
4. If the section has entries already, use the closing content of the last entry as the `old_string` anchor, and append the new entry after it
**BLOCKING — do not write to `docs/registry/architecture.yaml` without explicit user approval.**
Ask using `AskUserQuestion`:
- "May I update `docs/registry/architecture.yaml` with these [N] new stances?"
- Options: "Yes — update the registry", "Not yet — I want to review the candidates", "Skip registry update"
Only proceed if the user selects yes. If yes: append new entries. Never modify existing entries — if a stance is
changing, set the old entry to `status: superseded_by: ADR-[NNNN]` and add the new entry.
---
+9 -763
View File
@@ -9,8 +9,6 @@ model: opus
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow`
# Architecture Review
The architecture review validates that the complete body of architectural decisions
@@ -43,791 +41,39 @@ Every `AskUserQuestion` call follows `.claude/docs/automation-modes.md`
## Phase 1: Load Everything
### Phase 1a — L0: Summary Scan (fast, low tokens)
**Freshness check before any scan.** Locate the latest prior report — Glob
`docs/architecture/architecture-review-*.md` and take the newest — then:
```
Bash: bash .claude/scripts/review-receipts.sh check "[latest-report]" docs/architecture/adr-*.md design/gdd/*.md
```
- **Any `UNRESOLVED`** — check this FIRST; it disqualifies every option
below. One of the two globs matched no file, so that whole document class
was never examined and the comparison covered less than it appears to.
Say which pattern came back unresolved and stop: an ADR or GDD directory
that is empty, renamed or misspelled is a finding about the project, not a
reason to stand on a prior report. Never read a set of `UNCHANGED` lines as
"everything is current" while an `UNRESOLVED` line is present — the set
compared was not the set requested.
- **Everything `UNCHANGED`** (and no `UNRESOLVED`) — nothing this review
reads has changed since that report; re-running reproduces it. Surface the
prior report's date and verdict and offer via `AskUserQuestion`: `[A] Stand
on the prior report (Recommended)` / `[B] Re-run the full review anyway` —
`guided` proceeds with [A] and notes it; `autonomous` logs via
`log_decision` and stands on the prior report.
- **Some `CHANGED`/`NEW`** — name them, then scope instead of re-running
everything: recommend `/architecture-review [system]` (single-system mode)
for just the changed systems. A full re-run stays available on request,
and structural changes (a `NEW` ADR, a deleted file) warrant one.
- **`RECEIPT: NONE`** — no prior report, or one written before receipts
existed. Proceed with the full review; this run's report will carry the
first stamps.
Before reading any full document, use Grep to extract `## Summary` sections
from all GDDs and ADRs:
```
Grep pattern="## Summary" glob="design/gdd/*.md" output_mode="content" -A 4
Grep pattern="## Summary" glob="docs/architecture/adr-*.md" output_mode="content" -A 3
```
**Fail open on a missing Summary.** Establish the denominator: glob
`design/gdd/*.md` and count **N**. A scan matching fewer than N means those GDDs
predate `## Summary` (`/design-system` emits it, but older GDDs lack it) — never
treat an absent Summary as a system out of scope. A zero-match scan means "no GDD
carries a Summary yet", not "nothing to review": full-read the unmatched set.
For `single-gdd [path]` mode: use the target GDD's summary to identify which
ADRs reference the same system (Grep ADRs for the system name), then load only
those ADRs' sections per Phase 1b. Skip unrelated GDDs entirely.
For `engine` mode: load ADR sections only — GDDs are not needed for engine checks.
In practice this is the `## Engine Compatibility` scan alone.
For `coverage` or `full` mode: proceed to Phase 1b for the full in-scope set.
**This is a section load, not a full-file load** — see below for why, and for the
narrow cases that still justify escalating to a whole document.
### Phase 1b — L1/L2: Targeted Section Load
Load the sections the later phases actually consume — **not whole files**. This
skill reads the two largest document sets in the project (every GDD *and* every
ADR); at realistic sizes a full load of both exhausts the context window before
Phase 2 starts, and most of what it loads is narrative this skill never uses.
**Establish the denominator first.** Glob `design/gdd/*.md` and count **N_gdd**;
glob `docs/architecture/adr-*.md` and count **N_adr**. Report both. A section
scan matching fewer than the denominator means those documents lack the section —
**never treat an absent section as an absent document.** The scan narrows the
*read* set; it never shrinks the *in-scope* set.
### Design Documents
Phase 2 extracts *technical requirements* — data structures, performance
constraints, engine capabilities, cross-system communication, persistence,
threading, platform needs. Those live in a known set of sections; Overview and
Player Fantasy are narrative and yield none.
```
Grep pattern="^## (Detailed Rules|Detailed Design|Formulas|Dependencies|Tuning Knobs|Acceptance Criteria)" glob="design/gdd/*.md" output_mode="content" -A 40
```
Accept **either** `## Detailed Rules` or `## Detailed Design` — the design
standard and the GDD template disagree on the name and they denote the same
required section. Full-read a single GDD only when a scanned section
cross-references material outside itself, or when a GDD matched zero sections
(it predates the template — read it whole and say so).
- `design/gdd/systems-index.md` — the authoritative list of systems; read whole (small, and it is an index)
### Architecture Documents
Phases 3–5 need the traceability table, the decision itself, engine claims, and
the dependency edges — not Context, Consequences, Alternatives, Migration Plan or
Validation Criteria, which explain *why* a decision was made.
```
Grep pattern="^## (Status|Decision|GDD Requirements Addressed|Engine Compatibility|ADR Dependencies|Performance Implications)" glob="docs/architecture/adr-*.md" output_mode="content" -A 30
```
Interpret against **N_adr**, and distinguish the two zero-match cases — they are
not the same finding:
| Result | Meaning | Action |
|---|---|---|
| N_adr matches | Normal. | Proceed on the scanned sections. |
| Some ADRs match, some do not | Those ADRs are missing sections. | Record each as a **structural gap** in the Phase 7 report — a missing `## GDD Requirements Addressed` is itself a traceability finding. |
| **0 matches, N_adr > 0** | **Malformed ADRs**, not "no architecture". | "[N_adr] ADRs found, none carries a scannable section — run `/architecture-decision retrofit [file]` on each." Do **not** report zero coverage; that would read as a design failure when it is a format failure. |
Escalate to a full read of one ADR only when judging a conflict needs its
reasoning (Phase 4) — that is a per-ADR decision, not a blanket load.
- `docs/architecture/architecture.md` if it exists
### Engine Reference
- `docs/engine-reference/[engine]/VERSION.md`
- `docs/engine-reference/[engine]/breaking-changes.md`
- `docs/engine-reference/[engine]/deprecated-apis.md`
- **Only the module docs the in-scope ADRs actually name** — take the union of
each ADR's `References Consulted` and `Post-Cutoff APIs Used` fields (already
captured by the `## Engine Compatibility` scan above) and read those files.
Reading the whole `modules/` directory loads engine subsystems the project may
not use at all. If no ADR names any module, read none and note it: Phase 5
cannot cross-check engine claims that were never made.
### Project Standards
- `project.yaml` — `naming.*` and `performance.*`; plus `.claude/docs/technical-preferences.md` for those keys when absent and for forbidden patterns / allowed libraries
Report a count: "Loaded [N] GDDs, [M] ADRs, engine: [name + version]."
**Also read `docs/consistency-failures.md`** if it exists. Extract entries with
Domain matching the systems under review (Architecture, Engine, or any GDD domain
being covered). Surface recurring patterns as a "Known conflict-prone areas" note
at the top of the Phase 4 conflict detection output.
---
**Read `references/1-load.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 2: Extract Technical Requirements from Every GDD
### Pre-load the TR Registry
Before extracting any requirements, read `docs/architecture/tr-registry.yaml`
if it exists. Index existing entries by `id` and by normalized `requirement`
text (lowercase, trimmed). This prevents ID renumbering across review runs.
For each requirement you extract, the matching rule is:
1. **Exact/near match** to an existing registry entry for the same system →
reuse that entry's TR-ID unchanged. Update the `requirement` text in the
registry only if the GDD wording changed (same intent, clearer phrasing) —
add a `revised: [date]` field.
2. **No match** → assign a new ID: next available `TR-[system]-NNN` for that
system, starting from the highest existing sequence + 1.
3. **Ambiguous** (partial match, intent unclear) → ask the user:
> "Does '[new requirement text]' refer to the same requirement as
> `TR-[system]-NNN: [existing text]'`, or is it a new requirement?"
User answers: "Same requirement" (reuse ID) or "New requirement" (new ID).
For any requirement with `status: deprecated` in the registry — skip it.
It was removed from the GDD intentionally.
For each GDD, read it and extract all **technical requirements** — things the
architecture must provide for the system to work. A technical requirement is any
statement that implies a specific architectural decision.
Categories to extract:
| Category | Example |
|----------|---------|
| **Data structures** | "Each entity has health, max health, status effects" → needs a component/data schema |
| **Performance constraints** | "Collision detection must run at 60fps with 200 entities" → physics budget ADR |
| **Engine capability** | "Inverse kinematics for character animation" → IK system ADR |
| **Cross-system communication** | "Damage system notifies UI and audio simultaneously" → event/signal architecture ADR |
| **State persistence** | "Player progress persists between sessions" → save system ADR |
| **Threading/timing** | "AI decisions happen off the main thread" → concurrency ADR |
| **Platform requirements** | "Supports keyboard, gamepad, touch" → input system ADR |
For each GDD, produce a structured list:
```
GDD: [filename]
System: [system name]
Technical Requirements:
TR-[GDD]-001: [requirement text] → Domain: [Physics/Rendering/etc]
TR-[GDD]-002: [requirement text] → Domain: [...]
```
This becomes the **requirements baseline** — the complete set of what the
architecture must cover.
---
**Read `references/2-extract-requirements.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 3: Build the Traceability Matrix
For each technical requirement extracted in Phase 2, search the ADRs:
1. Use the ADRs **already loaded in Phase 1b** — do not re-read them. Extract each
ADR's "GDD Requirements Addressed" section from what is already in context.
(If Phase 1b ran in a mode that did not load every ADR, `Grep pattern="## GDD
Requirements Addressed" glob="docs/architecture/adr-*.md" output_mode="content"
-A 15` fills the gap without a full re-read.)
2. Check if it explicitly references the requirement or its GDD
3. Check if the ADR's decision text implicitly covers the requirement
4. Mark coverage status:
| Status | Meaning |
|--------|---------|
| ✅ **Covered** | An **Accepted** ADR explicitly addresses this requirement |
| 🟡 **Covered (Proposed)** | An ADR addresses it, but that ADR is still `Proposed` |
| ⚠️ **Partial** | An ADR partially covers this, or coverage is ambiguous |
| ❌ **Gap** | No ADR addresses this requirement |
| ❓ **Not assessed** | The ADR is unreadable, or has no `## Status` section |
> **Read each ADR's `## Status` before marking coverage — an unaccepted decision
> is not coverage.** If `✅` meant only that *an ADR addresses this*, with no
> status qualification, a requirement covered entirely by `Proposed` ADRs would
> count as covered and this review could return **PASS: All requirements
> covered** over an architecture nobody had accepted. Four skills downstream
> (`create-control-manifest`, `create-epics`, `create-stories`, `gate-check`)
> require `Accepted`, so a PASS on that basis sends work forward that every one
> of them will refuse.
>
> `🟡` is **not** a pass state: it caps the verdict at **CONCERNS**, and names the
> route out — `/architecture-decision accept ADR-NNNN`. That route is the only
> thing that moves an ADR to `Accepted`; without it, grading `Proposed` as
> covered would be the only option, which is why it must never be graded so.
Build the full matrix:
```
## Traceability Matrix
| Requirement ID | GDD | System | Requirement | ADR Coverage | Status |
|---------------|-----|--------|-------------|--------------|--------|
| TR-combat-001 | combat.md | Combat | Hitbox detection < 1 frame | ADR-0003 | ✅ |
| TR-combat-002 | combat.md | Combat | Combo window timing | — | ❌ GAP |
| TR-inventory-001 | inventory.md | Inventory | Persistent item storage | ADR-0005 | ✅ |
```
Count the totals: X covered, Y partial, Z gaps.
---
## Phase 3b: Story and Test Linkage (RTM mode only)
*Skip this phase unless the argument is `rtm` or `full` with stories present.*
This phase extends the Phase 3 matrix to include the story that implements
each requirement and the test that verifies it — producing the full
Requirements Traceability Matrix (RTM).
### Step 3b-1 — Load stories
Glob `production/epics/**/*.md` (excluding EPIC.md index files) to establish the
denominator. Then collect the fields with **targeted section greps, not a full
read of each story** — the same two-grep form `/test-evidence-review` uses for
this identical extraction:
```
Grep pattern="## Test Evidence" glob="production/epics/**/story-*.md" output_mode="content" -A 8
Grep pattern="TR-" glob="production/epics/**/story-*.md" output_mode="content"
```
- **TR-ID** — from the second grep.
- **Test file path** — under `## Test Evidence`, captured by the first grep's `-A 8`.
- **Status** — from the story header; add `Grep pattern="^> \*\*Status\*\*"` if not already captured.
- **Story path and title** — from the file name and path; no read at all.
Full-read a story only when its Test Evidence section is missing or ambiguous.
### Step 3b-2 — Load test files
Glob the engine's test root (`.claude/docs/directory-structure.md`): Godot
`tests/unit/**/*_test.*` and `tests/integration/**/*_test.*`; Unity
`Assets/Tests/**/*Tests.cs`; Unreal `Source/*/Private/Tests/**/*.cpp`. With no
engine configured, say the test index could not be built rather than reading an
empty glob as "no tests". Build an index: system → [test file paths].
For each test file path from Step 3b-1, confirm via Glob whether the file
actually exists. Note MISSING if the stated path does not exist.
### Step 3b-3 — Build the extended RTM
For each TR-ID in the Phase 3 matrix, add:
- **Story**: the story file path(s) that reference this TR-ID (may be multiple)
- **Test File**: the test file path stated in the story's Test Evidence section
- **Test Status**: COVERED (test file exists) / MISSING (path stated but not
found) / NONE (no test path stated, story type may be Visual/Feel/UI) /
NO STORY (requirement has no story yet — pre-production gap)
Extended matrix format:
```
## Requirements Traceability Matrix (RTM)
| TR-ID | GDD | Requirement | ADR | Story | Test File | Test Status |
|-------|-----|-------------|-----|-------|-----------|-------------|
| TR-combat-001 | combat.md | Hitbox < 1 frame | ADR-0003 | story-001-hitbox.md | tests/unit/combat/hitbox_test.gd | COVERED |
| TR-combat-002 | combat.md | Combo window | — | story-002-combo.md | — | NONE (Visual/Feel) |
| TR-inventory-001 | inventory.md | Persistent storage | ADR-0005 | — | — | NO STORY |
```
RTM coverage summary:
- COVERED: [N] — requirements with ADR + story + passing test
- MISSING test: [N] — story exists but test file not found
- NO STORY: [N] — requirements with ADR but no story yet
- NO ADR: [N] — requirements without architectural coverage (from Phase 3 gaps)
- Full chain complete (COVERED): [N/total] ([%])
---
**Read `references/3-traceability.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 4: Cross-ADR Conflict Detection
Compare every ADR against every other ADR to detect contradictions. A conflict
exists when:
- **Data ownership conflict**: Two ADRs claim exclusive ownership of the same data
- **Integration contract conflict**: ADR-A assumes System X has interface Y, but
ADR-B defines System X with a different interface
- **Performance budget conflict**: ADR-A allocates N ms to physics, ADR-B allocates
N ms to AI, together they exceed the total frame budget
- **Dependency cycle**: ADR-A says System X initialises before Y; ADR-B says Y
initialises before X
- **Architecture pattern conflict**: ADR-A uses event-driven communication for a
subsystem; ADR-B uses direct function calls to the same subsystem
- **State management conflict**: Two ADRs define authority over the same game state
(e.g. both Combat ADR and Character ADR claim to own the health value)
For each conflict found:
```
## Conflict: [ADR-NNNN] vs [ADR-MMMM]
Type: [Data ownership / Integration / Performance / Dependency / Pattern / State]
ADR-NNNN claims: [...]
ADR-MMMM claims: [...]
Impact: [What breaks if both are implemented as written]
Resolution options:
1. [Option A]
2. [Option B]
```
### ADR Dependency Ordering
After conflict detection, analyse the dependency graph across all ADRs.
**Build the graph deterministically — do not trace it by hand:**
```
Bash: bash .claude/scripts/adr-dep-graph.sh
```
It collects every `Depends On` edge, runs Kahn's algorithm, and emits
`ADRS:` / `EDGES:` / `NO_DEPS_SECTION:` / `CYCLE:`. A model tracing A→B→C→A across
a dozen ADRs eventually misses an edge; the algorithm cannot. It reports
observations, not a verdict — you apply the meaning below.
**`NO_DEPS_SECTION` is load-bearing**: it makes "no cycles because the graph is
clean" distinguishable from "no cycles because half the ADRs declare no
dependencies". Report the second case as a structural gap, never as a clean graph.
Then interpret:
1. **Topological sort**: the emitted order — ADRs with no
dependencies come first (Foundation), ADRs that depend on those come next, etc.
2. **Flag unresolved dependencies**: cross the `EDGES:` list against the `## Status`
values already scanned in Phase 1b. If ADR-A depends on an ADR that is still
`Proposed` or does not exist, flag it:
```
⚠️ ADR-0005 depends on ADR-0002 — but ADR-0002 is still Proposed.
ADR-0005 cannot be safely implemented until ADR-0002 is Accepted.
```
3. **Cycle detection**: every `CYCLE:` line the script emitted is a
`DEPENDENCY CYCLE` — report each one. Do not re-derive them by hand:
```
🔴 DEPENDENCY CYCLE: ADR-0003 → ADR-0006 → ADR-0003
This cycle must be broken before either can be implemented.
```
4. **Output recommended implementation order**:
```
### Recommended ADR Implementation Order (topologically sorted)
Foundation (no dependencies):
1. ADR-0001: [title]
2. ADR-0003: [title]
Depends on Foundation:
3. ADR-0002: [title] (requires ADR-0001)
4. ADR-0005: [title] (requires ADR-0003)
Feature layer:
5. ADR-0004: [title] (requires ADR-0002, ADR-0005)
```
---
**Read `references/4-conflicts.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 5: Engine Compatibility Cross-Check
Across all ADRs, check for engine consistency:
### Version Consistency
- Do all ADRs that mention an engine version agree on the same version?
- If any ADR was written for an older engine version, flag it as potentially stale
### Post-Cutoff API Consistency
- Collect all "Post-Cutoff APIs Used" fields from all ADRs
- For each, verify against the relevant module reference doc
- Check that no two ADRs make contradictory assumptions about the same post-cutoff API
### Deprecated API Check
- Grep all ADRs for API names listed in `deprecated-apis.md`
- Flag any ADR referencing a deprecated API
### Missing Engine Compatibility Sections
- List all ADRs that are missing the Engine Compatibility section entirely
- These are blind spots — their engine assumptions are unknown
Output format:
```
### Engine Audit Results
Engine: [name + version]
ADRs with Engine Compatibility section: X / Y total
Deprecated API References:
- ADR-0002: uses [deprecated API] — deprecated since [version]
Stale Version References:
- ADR-0001: written for [older version] — current project version is [version]
Post-Cutoff API Conflicts:
- ADR-0004 and ADR-0007 both use [API] with incompatible assumptions
```
---
### Engine Specialist Consultation
After completing the engine audit above, spawn the **primary engine specialist** via `Agent` for a domain-expert second opinion:
- Resolve the primary specialist: `<engine>-specialist` derived from `engine.name` in `project.yaml` (Godot→`godot-specialist`, Unity→`unity-specialist`, Unreal→`unreal-specialist`); if `engine.name` is absent or empty, read the Primary line of the `## Engine Specialists` section in `.claude/docs/technical-preferences.md`
- If no engine is configured (neither source yields an engine), skip this consultation **Record ``Engine validation: NOT ASSESSED — no engine configured (`engine.name` unset in `project.yaml`)`` in this run's output.** A skipped check that says nothing is indistinguishable from a check that passed; the reader cannot tell engine guidance was never sought.
- Spawn `subagent_type: [primary specialist]` with: all ADRs that contain engine-specific decisions or `Post-Cutoff APIs Used` fields, the engine reference docs, and the Phase 5 audit findings. Ask them to:
1. Confirm or challenge each audit finding — specialists may know of engine nuances not captured in the reference docs
2. Identify engine-specific anti-patterns in the ADRs that the audit may have missed (e.g., using the wrong Godot node type, Unity component coupling, Unreal subsystem misuse)
3. Flag ADRs that make assumptions about engine behaviour that differ from the actual pinned version
Incorporate additional findings under `### Engine Specialist Findings` in the Phase 5 output. These feed into the final verdict — specialist-identified issues carry the same weight as audit-identified issues.
---
## Phase 5b: Design Revision Flags (Architecture → GDD Feedback)
For each **HIGH RISK engine finding** from Phase 5, check whether any GDD makes an
assumption that the verified engine reality contradicts.
Specific cases to check:
1. **Post-cutoff API behaviour differs from training-data assumptions**: If an ADR
records a verified API behaviour that differs from the default LLM assumption,
check all GDDs that reference the related system. Look for design rules written
around the old (assumed) behaviour.
2. **Known engine limitations in ADRs**: If an ADR records a known engine limitation
(e.g. "Jolt ignores HingeJoint3D damp", "D3D12 is now the default backend"), check
GDDs that design mechanics around the affected feature.
3. **Deprecated API conflicts**: If Phase 5 flagged a deprecated API used in an ADR,
check whether any GDD contains mechanics that assume the deprecated API's behaviour.
For each conflict found, record it in the GDD Revision Flags table:
```
### GDD Revision Flags (Architecture → Design Feedback)
These GDD assumptions conflict with verified engine behaviour or accepted ADRs.
The GDD should be revised before its system enters implementation.
| GDD | Assumption | Reality (from ADR/engine-reference) | Action |
|-----|-----------|--------------------------------------|--------|
| combat.md | "Use HingeJoint3D damp for weapon recoil" | Jolt ignores damp — ADR-0003 | Revise GDD |
```
If no revision flags are found, write: "No GDD revision flags — all GDD assumptions
are consistent with verified engine behaviour."
Before asking, display the proposed change inline — show the current systems-index row for each flagged GDD and the proposed updated row side by side so the user can see exactly what will change.
Then use `AskUserQuestion`:
- "I found [N] GDD revision flag(s). May I update the systems index?"
- [A] Yes — apply all [N] updates to the systems index now
- [B] Show me the full diff first, then ask again
- [C] No — leave the systems index unchanged for now
If [A]: apply the updates. Status field must be exactly `Needs Revision` — no parentheticals
(other skills match that exact string and parentheticals break the match).
If [B]: display the complete proposed systems-index section, then re-ask with `AskUserQuestion`.
---
**Read `references/5-engine.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 6: Architecture Document Coverage
**If `docs/architecture/architecture.md` does not exist, say so in the report** —
`Architecture document coverage: NOT ASSESSED — no docs/architecture/architecture.md`
— and carry it into the Phase 7 verdict per the trigger list below. Phase 5
already models this for the engine consultation (*"A skipped check that says
nothing is indistinguishable from a check that passed"*); this phase is the one
that did not. Silently producing no Phase 6 findings reads as an architecture
document that was checked and found clean, which is the opposite of what
happened.
If it exists, validate it against GDDs:
- Does every system from `systems-index.md` appear in the architecture layers?
- Does the data flow section cover all cross-system communication defined in GDDs?
- Do the API boundaries support all integration requirements from GDDs?
- Are there systems in the architecture doc that have no corresponding GDD
(orphaned architecture)?
---
**Read `references/6-document-coverage.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 7: Output the Review Report
```
## Architecture Review Report
Date: [date]
Engine: [name + version]
GDDs Reviewed: [N]
ADRs Reviewed: [M]
[output of: Bash: bash .claude/scripts/review-receipts.sh hash docs/architecture/adr-*.md design/gdd/*.md
— one Reviewed-Content-Hash line per file reviewed; Phase 1a's freshness
check reads these on the next run to skip or scope an unchanged re-review]
---
### Traceability Summary
Total requirements: [N]
✅ Covered: [X]
⚠️ Partial: [Y]
❌ Gaps: [Z]
### Coverage Gaps (no ADR exists)
For each gap:
❌ TR-[id]: [GDD] → [system] → [requirement]
Suggested ADR: "/architecture-decision [suggested title]"
Domain: [Physics/Rendering/etc]
Engine Risk: [LOW/MEDIUM/HIGH]
### Cross-ADR Conflicts
[List all conflicts from Phase 4]
### ADR Dependency Order
[Topologically sorted implementation order from Phase 4 — dependency ordering section]
[Unresolved dependencies and cycles if any]
### GDD Revision Flags
[GDD assumptions that conflict with verified engine behaviour — from Phase 5b]
[Or: "None — all GDD assumptions consistent with verified engine behaviour"]
### Engine Compatibility Issues
[List all engine issues from Phase 5]
### Architecture Document Coverage
[List missing systems and orphaned architecture from Phase 6]
---
### Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
PASS: All requirements covered by **Accepted** ADRs, no conflicts, engine consistent
NOT ASSESSED: The review could not be performed over its stated scope — name why
CONCERNS: Some gaps, partial coverage, or coverage resting on `Proposed` ADRs,
but no blocking conflicts
FAIL: Critical gaps (Foundation/Core layer requirements uncovered),
or blocking cross-ADR conflicts detected
**`NOT ASSESSED` ranks above PASS and below CONCERNS and FAIL.** Emit it when:
- **No ADRs exist, or none could be read.** Zero requirements traced is not full
coverage — it is an untraced architecture, and a matrix of `❌ Gap` rows at
least says so while an empty matrix says nothing.
- **The requirement source is missing** — no `tr-registry.yaml` and no GDD
requirements to trace *from*. A review with no left-hand column cannot report
coverage; it can only report that it had nothing to compare.
- **An ADR is unreadable or has no `## Status`**, so its rows are `❓` and their
coverage is unknown rather than absent.
- **Phase 6 could not run** — no `docs/architecture/architecture.md`. It must
appear as a named `NOT ASSESSED` **line item** in the report rather than as
absent findings. ADR traceability can still be complete, so a CONCERNS or FAIL
finding elsewhere still stands; but in `full` mode, whose scope includes
Phase 6, the verdict cannot be PASS — a review that could not look at part of
its scope has not shown that part is sound, so it is NOT ASSESSED.
- **No engine is configured** (`full` and `engine` modes) — Phase 5 has no pinned
engine reference to audit the ADRs against, and the specialist consultation was
skipped. Record the `Engine validation: NOT ASSESSED` line item; like Phase 6
above, it keeps the verdict from PASS.
Do not resolve any of these to PASS on the grounds that no gap was *found*. No
gap was looked for.
### Blocking Issues (must resolve before PASS)
[List items that must be resolved — FAIL verdict only]
### Required ADRs
[Prioritised list of ADRs to create, most foundational first]
```
---
**Read `references/7-report.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 8: Write and Update Traceability Index
Use `AskUserQuestion` for the write approval:
- "Review complete. What would you like to write?"
- [A] Write all three files — review report (`docs/architecture/architecture-review-[date].md`), traceability index (`docs/architecture/requirements-traceability.md`), TR registry (`docs/architecture/tr-registry.yaml`)
- [B] Write review report only — `docs/architecture/architecture-review-[date].md`
- [C] Don't write anything yet — I need to review the findings first
When Phase 4 found a 🔴 conflict and `docs/consistency-failures.md` exists, name
that file in option [A] as well — "…and append [N] conflict entr(y/ies) to
`docs/consistency-failures.md`". Only [A] appends there (see Reflexion Log
Update); [B] writes the report and nothing else.
### RTM Output (rtm mode only)
For `rtm` mode, use `AskUserQuestion`:
- "May I write the full Requirements Traceability Matrix?"
- [A] Yes — write to `docs/architecture/requirements-traceability.md`
- [B] Not yet — show me the full RTM data first, then ask again
RTM file format:
```markdown
# Requirements Traceability Matrix (RTM)
> Last Updated: [date]
> Mode: /architecture-review rtm
> Coverage: [N]% full chain complete (GDD → ADR → Story → Test)
## How to read this matrix
| Column | Meaning |
|--------|---------|
| TR-ID | Stable requirement ID from tr-registry.yaml |
| GDD | Source design document |
| ADR | Architectural decision governing implementation |
| Story | Story file that implements this requirement |
| Test File | Automated test file path |
| Test Status | COVERED / MISSING / NONE / NO STORY |
## Full Traceability Matrix
| TR-ID | GDD | Requirement | ADR | Story | Test File | Status |
|-------|-----|-------------|-----|-------|-----------|--------|
[Full matrix rows from Phase 3b]
## Coverage Summary
| Status | Count | % |
|--------|-------|---|
| COVERED — full chain complete | [N] | [%] |
| MISSING test — story exists, no test | [N] | [%] |
| NO STORY — ADR exists, not yet implemented | [N] | [%] |
| NO ADR — architectural gap | [N] | [%] |
| **Total requirements** | **[N]** | **100%** |
## Uncovered Requirements (Priority Fix List)
Requirements where the full chain is broken, prioritised by layer:
### Foundation layer gaps
[list with suggested action per gap]
### Core layer gaps
[list]
### Feature / Presentation layer gaps
[list — lower priority]
## History
| Date | Full Chain % | Notes |
|------|-------------|-------|
| [date] | [%] | Initial RTM |
```
### TR Registry Update
Also ask: "May I update `docs/architecture/tr-registry.yaml` with new requirement
IDs from this review?"
If yes:
- **Append** any new TR-IDs that weren't in the registry before this review
- **Update** `requirement` text and `revised` date for any entries whose GDD
wording changed (ID stays the same)
- **Mark** `status: deprecated` for any registry entries whose GDD requirement
no longer exists (confirm with user before marking deprecated)
- **Never** renumber or delete existing entries
- Update the `last_updated` and `version` fields at the top
This ensures all future story files can reference stable TR-IDs that persist
across every subsequent architecture review.
### Reflexion Log Update
When the user chose Phase 8's [A] — the option that named this file — append
any 🔴 CONFLICT entries found in Phase 4 to `docs/consistency-failures.md` (if
the file exists), after writing the review report:
```markdown
### [YYYY-MM-DD] — /architecture-review — 🔴 CONFLICT
**Domain**: Architecture / [specific domain e.g. State Ownership, Performance]
**Documents involved**: [ADR-NNNN] vs [ADR-MMMM]
**What happened**: [specific conflict — what each ADR claims]
**Resolution**: [how it was or should be resolved]
**Pattern**: [generalised lesson for future ADR authors in this domain]
```
Only append CONFLICT entries — do not log GAP entries (missing ADRs are expected
before the architecture is complete). Do not create the file if missing — only
append when it already exists.
### Session State Update
After writing all approved files, silently append to
`production/session-state/active.md`:
## Session Extract — /architecture-review [date]
- Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
- Requirements: [N] total — [X] covered, [Y] partial, [Z] gaps
- New TR-IDs registered: [N, or "None"]
- GDD revision flags: [comma-separated GDD names, or "None"]
- Top ADR gaps: [top 3 gap titles from the report, or "None"]
- Report: docs/architecture/architecture-review-[date].md
If `active.md` does not exist, create it with this block as the initial content.
Confirm in conversation: "Session state updated."
The traceability index — written to `docs/architecture/requirements-traceability.md`,
the path `/propagate-design-change` and the Pre-Production gate read; `rtm` mode
later extends the same file with story and test columns — uses this format:
```markdown
# Architecture Traceability Index
Last Updated: [date]
Engine: [name + version]
## Coverage Summary
- Total requirements: [N]
- Covered: [X] ([%])
- Partial: [Y]
- Gaps: [Z]
## Full Matrix
[Complete traceability matrix from Phase 3]
## Known Gaps
[All ❌ items with suggested ADRs]
## Superseded Requirements
[Requirements whose GDD was changed after the ADR was written]
```
---
**Read `references/8-write.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 9: Handoff
After completing the review and writing approved files, present:
1. **Immediate actions**: List the top 3 ADRs to create (highest-impact gaps first,
Foundation layer before Feature layer)
2. **Pre-gate checklist**: Check whether these exist via Glob and mark each ✅ or ❌:
- the engine's test root — `tests/unit/` and `tests/integration/` (Godot), `Assets/Tests/EditMode/` and `Assets/Tests/PlayMode/` (Unity), `Source/<Module>/Private/Tests/` (Unreal) — if ❌: run `/test-setup`
- `.github/workflows/tests.yml` — if ❌: run `/test-setup`
- `design/accessibility-requirements.md` — if ❌: run `/ux-design`
- `design/ux/interaction-patterns.md` — if ❌: run `/ux-design`
Present ❌ items as required steps before gate-check. Do not offer `/gate-check`
as an option if any item is ❌ — offer the missing skill to run instead.
3. **Rerun trigger**: "Re-run `/architecture-review` after each new ADR is written
to verify coverage improves"
Then close with `AskUserQuestion` tailored to the pre-gate checklist state:
- If ADR gaps remain or any pre-gate item is ❌:
- "Architecture review complete. What would you like to do next?"
- [A] Write a missing ADR — open a fresh session and run `/architecture-decision [system]`
- [B] Run `/test-setup` — required before gate-check (only show if test infrastructure is ❌)
- [C] Run `/ux-design` — required before gate-check (only show if UX/accessibility files are ❌)
- [D] Stop here for this session
- If all pre-gate checklist items are ✅ and no blocking ADR gaps remain:
- "Architecture review complete. All pre-gate items confirmed. What would you like to do next?"
- [A] Run `/gate-check pre-production`
- [B] Write a missing ADR — open a fresh session and run `/architecture-decision [system]`
- [C] Stop here for this session
---
**Read `references/9-handoff.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Error Recovery Protocol
@@ -0,0 +1,150 @@
# /architecture-review — Phase 1: Load Everything
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 1: Load Everything
**In this file:**
- Phase 1a — L0: Summary Scan (fast, low tokens)
- Phase 1b — L1/L2: Targeted Section Load
- Design Documents
- Architecture Documents
- Engine Reference
- Project Standards
### Phase 1a — L0: Summary Scan (fast, low tokens)
**Freshness check before any scan.** Locate the latest prior report — Glob
`docs/architecture/architecture-review-*.md` and take the newest — then:
```
Bash: bash .claude/scripts/review-receipts.sh check "[latest-report]" docs/architecture/adr-*.md design/gdd/*.md
```
- **Any `UNRESOLVED`** — check this FIRST; it disqualifies every option
below. One of the two globs matched no file, so that whole document class
was never examined and the comparison covered less than it appears to.
Say which pattern came back unresolved and stop: an ADR or GDD directory
that is empty, renamed or misspelled is a finding about the project, not a
reason to stand on a prior report. Never read a set of `UNCHANGED` lines as
"everything is current" while an `UNRESOLVED` line is present — the set
compared was not the set requested.
- **Everything `UNCHANGED`** (and no `UNRESOLVED`) — nothing this review
reads has changed since that report; re-running reproduces it. Surface the
prior report's date and verdict and offer via `AskUserQuestion`: `[A] Stand
on the prior report (Recommended)` / `[B] Re-run the full review anyway` —
`guided` proceeds with [A] and notes it; `autonomous` logs via
`log_decision` and stands on the prior report.
- **Some `CHANGED`/`NEW`** — name them, then scope instead of re-running
everything: recommend `/architecture-review [system]` (single-system mode)
for just the changed systems. A full re-run stays available on request,
and structural changes (a `NEW` ADR, a deleted file) warrant one.
- **`RECEIPT: NONE`** — no prior report, or one written before receipts
existed. Proceed with the full review; this run's report will carry the
first stamps.
Before reading any full document, use Grep to extract `## Summary` sections
from all GDDs and ADRs:
```
Grep pattern="## Summary" glob="design/gdd/*.md" output_mode="content" -A 4
Grep pattern="## Summary" glob="docs/architecture/adr-*.md" output_mode="content" -A 3
```
**Fail open on a missing Summary.** Establish the denominator: glob
`design/gdd/*.md` and count **N**. A scan matching fewer than N means those GDDs
predate `## Summary` (`/design-system` emits it, but older GDDs lack it) — never
treat an absent Summary as a system out of scope. A zero-match scan means "no GDD
carries a Summary yet", not "nothing to review": full-read the unmatched set.
For `single-gdd [path]` mode: use the target GDD's summary to identify which
ADRs reference the same system (Grep ADRs for the system name), then load only
those ADRs' sections per Phase 1b. Skip unrelated GDDs entirely.
For `engine` mode: load ADR sections only — GDDs are not needed for engine checks.
In practice this is the `## Engine Compatibility` scan alone.
For `coverage` or `full` mode: proceed to Phase 1b for the full in-scope set.
**This is a section load, not a full-file load** — see below for why, and for the
narrow cases that still justify escalating to a whole document.
### Phase 1b — L1/L2: Targeted Section Load
Load the sections the later phases actually consume — **not whole files**. This
skill reads the two largest document sets in the project (every GDD *and* every
ADR); at realistic sizes a full load of both exhausts the context window before
Phase 2 starts, and most of what it loads is narrative this skill never uses.
**Establish the denominator first.** Glob `design/gdd/*.md` and count **N_gdd**;
glob `docs/architecture/adr-*.md` and count **N_adr**. Report both. A section
scan matching fewer than the denominator means those documents lack the section —
**never treat an absent section as an absent document.** The scan narrows the
*read* set; it never shrinks the *in-scope* set.
### Design Documents
Phase 2 extracts *technical requirements* — data structures, performance
constraints, engine capabilities, cross-system communication, persistence,
threading, platform needs. Those live in a known set of sections; Overview and
Player Fantasy are narrative and yield none.
```
Grep pattern="^## (Detailed Rules|Detailed Design|Formulas|Dependencies|Tuning Knobs|Acceptance Criteria)" glob="design/gdd/*.md" output_mode="content" -A 40
```
Accept **either** `## Detailed Rules` or `## Detailed Design` — the design
standard and the GDD template disagree on the name and they denote the same
required section. Full-read a single GDD only when a scanned section
cross-references material outside itself, or when a GDD matched zero sections
(it predates the template — read it whole and say so).
- `design/gdd/systems-index.md` — the authoritative list of systems; read whole (small, and it is an index)
### Architecture Documents
Phases 3–5 need the traceability table, the decision itself, engine claims, and
the dependency edges — not Context, Consequences, Alternatives, Migration Plan or
Validation Criteria, which explain *why* a decision was made.
```
Grep pattern="^## (Status|Decision|GDD Requirements Addressed|Engine Compatibility|ADR Dependencies|Performance Implications)" glob="docs/architecture/adr-*.md" output_mode="content" -A 30
```
Interpret against **N_adr**, and distinguish the two zero-match cases — they are
not the same finding:
| Result | Meaning | Action |
|---|---|---|
| N_adr matches | Normal. | Proceed on the scanned sections. |
| Some ADRs match, some do not | Those ADRs are missing sections. | Record each as a **structural gap** in the Phase 7 report — a missing `## GDD Requirements Addressed` is itself a traceability finding. |
| **0 matches, N_adr > 0** | **Malformed ADRs**, not "no architecture". | "[N_adr] ADRs found, none carries a scannable section — run `/architecture-decision retrofit [file]` on each." Do **not** report zero coverage; that would read as a design failure when it is a format failure. |
Escalate to a full read of one ADR only when judging a conflict needs its
reasoning (Phase 4) — that is a per-ADR decision, not a blanket load.
- `docs/architecture/architecture.md` if it exists
### Engine Reference
- `docs/engine-reference/[engine]/VERSION.md`
- `docs/engine-reference/[engine]/breaking-changes.md`
- `docs/engine-reference/[engine]/deprecated-apis.md`
- **Only the module docs the in-scope ADRs actually name** — take the union of
each ADR's `References Consulted` and `Post-Cutoff APIs Used` fields (already
captured by the `## Engine Compatibility` scan above) and read those files.
Reading the whole `modules/` directory loads engine subsystems the project may
not use at all. If no ADR names any module, read none and note it: Phase 5
cannot cross-check engine claims that were never made.
### Project Standards
- `project.yaml` — `naming.*` and `performance.*`; plus `.claude/docs/technical-preferences.md` for those keys when absent and for forbidden patterns / allowed libraries
Report a count: "Loaded [N] GDDs, [M] ADRs, engine: [name + version]."
**Also read `docs/consistency-failures.md`** if it exists. Extract entries with
Domain matching the systems under review (Architecture, Engine, or any GDD domain
being covered). Surface recurring patterns as a "Known conflict-prone areas" note
at the top of the Phase 4 conflict detection output.
---
@@ -0,0 +1,58 @@
# /architecture-review — Phase 2: Extract Technical Requirements
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 2: Extract Technical Requirements from Every GDD
### Pre-load the TR Registry
Before extracting any requirements, read `docs/architecture/tr-registry.yaml`
if it exists. Index existing entries by `id` and by normalized `requirement`
text (lowercase, trimmed). This prevents ID renumbering across review runs.
For each requirement you extract, the matching rule is:
1. **Exact/near match** to an existing registry entry for the same system →
reuse that entry's TR-ID unchanged. Update the `requirement` text in the
registry only if the GDD wording changed (same intent, clearer phrasing) —
add a `revised: [date]` field.
2. **No match** → assign a new ID: next available `TR-[system]-NNN` for that
system, starting from the highest existing sequence + 1.
3. **Ambiguous** (partial match, intent unclear) → ask the user:
> "Does '[new requirement text]' refer to the same requirement as
> `TR-[system]-NNN: [existing text]'`, or is it a new requirement?"
User answers: "Same requirement" (reuse ID) or "New requirement" (new ID).
For any requirement with `status: deprecated` in the registry — skip it.
It was removed from the GDD intentionally.
For each GDD, read it and extract all **technical requirements** — things the
architecture must provide for the system to work. A technical requirement is any
statement that implies a specific architectural decision.
Categories to extract:
| Category | Example |
|----------|---------|
| **Data structures** | "Each entity has health, max health, status effects" → needs a component/data schema |
| **Performance constraints** | "Collision detection must run at 60fps with 200 entities" → physics budget ADR |
| **Engine capability** | "Inverse kinematics for character animation" → IK system ADR |
| **Cross-system communication** | "Damage system notifies UI and audio simultaneously" → event/signal architecture ADR |
| **State persistence** | "Player progress persists between sessions" → save system ADR |
| **Threading/timing** | "AI decisions happen off the main thread" → concurrency ADR |
| **Platform requirements** | "Supports keyboard, gamepad, touch" → input system ADR |
For each GDD, produce a structured list:
```
GDD: [filename]
System: [system name]
Technical Requirements:
TR-[GDD]-001: [requirement text] → Domain: [Physics/Rendering/etc]
TR-[GDD]-002: [requirement text] → Domain: [...]
```
This becomes the **requirements baseline** — the complete set of what the
architecture must cover.
---
@@ -0,0 +1,129 @@
# /architecture-review — Phases 3 and 3b: Traceability Matrix and Story Linkage
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 3: Build the Traceability Matrix
**In this file:**
- Step 3b-1 — Load stories
- Step 3b-2 — Load test files
- Step 3b-3 — Build the extended RTM
For each technical requirement extracted in Phase 2, search the ADRs:
1. Use the ADRs **already loaded in Phase 1b** — do not re-read them. Extract each
ADR's "GDD Requirements Addressed" section from what is already in context.
(If Phase 1b ran in a mode that did not load every ADR, `Grep pattern="## GDD
Requirements Addressed" glob="docs/architecture/adr-*.md" output_mode="content"
-A 15` fills the gap without a full re-read.)
2. Check if it explicitly references the requirement or its GDD
3. Check if the ADR's decision text implicitly covers the requirement
4. Mark coverage status:
| Status | Meaning |
|--------|---------|
| ✅ **Covered** | An **Accepted** ADR explicitly addresses this requirement |
| 🟡 **Covered (Proposed)** | An ADR addresses it, but that ADR is still `Proposed` |
| ⚠️ **Partial** | An ADR partially covers this, or coverage is ambiguous |
| ❌ **Gap** | No ADR addresses this requirement |
| ❓ **Not assessed** | The ADR is unreadable, or has no `## Status` section |
> **Read each ADR's `## Status` before marking coverage — an unaccepted decision
> is not coverage.** If `✅` meant only that *an ADR addresses this*, with no
> status qualification, a requirement covered entirely by `Proposed` ADRs would
> count as covered and this review could return **PASS: All requirements
> covered** over an architecture nobody had accepted. Four skills downstream
> (`create-control-manifest`, `create-epics`, `create-stories`, `gate-check`)
> require `Accepted`, so a PASS on that basis sends work forward that every one
> of them will refuse.
>
> `🟡` is **not** a pass state: it caps the verdict at **CONCERNS**, and names the
> route out — `/architecture-decision accept ADR-NNNN`. That route is the only
> thing that moves an ADR to `Accepted`; without it, grading `Proposed` as
> covered would be the only option, which is why it must never be graded so.
Build the full matrix:
```
## Traceability Matrix
| Requirement ID | GDD | System | Requirement | ADR Coverage | Status |
|---------------|-----|--------|-------------|--------------|--------|
| TR-combat-001 | combat.md | Combat | Hitbox detection < 1 frame | ADR-0003 | ✅ |
| TR-combat-002 | combat.md | Combat | Combo window timing | — | ❌ GAP |
| TR-inventory-001 | inventory.md | Inventory | Persistent item storage | ADR-0005 | ✅ |
```
Count the totals: X covered, Y partial, Z gaps.
---
## Phase 3b: Story and Test Linkage (RTM mode only)
*Skip this phase unless the argument is `rtm` or `full` with stories present.*
This phase extends the Phase 3 matrix to include the story that implements
each requirement and the test that verifies it — producing the full
Requirements Traceability Matrix (RTM).
### Step 3b-1 — Load stories
Glob `production/epics/**/*.md` (excluding EPIC.md index files) to establish the
denominator. Then collect the fields with **targeted section greps, not a full
read of each story** — the same two-grep form `/test-evidence-review` uses for
this identical extraction:
```
Grep pattern="## Test Evidence" glob="production/epics/**/story-*.md" output_mode="content" -A 8
Grep pattern="TR-" glob="production/epics/**/story-*.md" output_mode="content"
```
- **TR-ID** — from the second grep.
- **Test file path** — under `## Test Evidence`, captured by the first grep's `-A 8`.
- **Status** — from the story header; add `Grep pattern="^> \*\*Status\*\*"` if not already captured.
- **Story path and title** — from the file name and path; no read at all.
Full-read a story only when its Test Evidence section is missing or ambiguous.
### Step 3b-2 — Load test files
Glob the engine's test root (`.claude/docs/directory-structure.md`): Godot
`tests/unit/**/*_test.*` and `tests/integration/**/*_test.*`; Unity
`Assets/Tests/**/*Tests.cs`; Unreal `Source/*/Private/Tests/**/*.cpp`. With no
engine configured, say the test index could not be built rather than reading an
empty glob as "no tests". Build an index: system → [test file paths].
For each test file path from Step 3b-1, confirm via Glob whether the file
actually exists. Note MISSING if the stated path does not exist.
### Step 3b-3 — Build the extended RTM
For each TR-ID in the Phase 3 matrix, add:
- **Story**: the story file path(s) that reference this TR-ID (may be multiple)
- **Test File**: the test file path stated in the story's Test Evidence section
- **Test Status**: COVERED (test file exists) / MISSING (path stated but not
found) / NONE (no test path stated, story type may be Visual/Feel/UI) /
NO STORY (requirement has no story yet — pre-production gap)
Extended matrix format:
```
## Requirements Traceability Matrix (RTM)
| TR-ID | GDD | Requirement | ADR | Story | Test File | Test Status |
|-------|-----|-------------|-----|-------|-----------|-------------|
| TR-combat-001 | combat.md | Hitbox < 1 frame | ADR-0003 | story-001-hitbox.md | tests/unit/combat/hitbox_test.gd | COVERED |
| TR-combat-002 | combat.md | Combo window | — | story-002-combo.md | — | NONE (Visual/Feel) |
| TR-inventory-001 | inventory.md | Persistent storage | ADR-0005 | — | — | NO STORY |
```
RTM coverage summary:
- COVERED: [N] — requirements with ADR + story + passing test
- MISSING test: [N] — story exists but test file not found
- NO STORY: [N] — requirements with ADR but no story yet
- NO ADR: [N] — requirements without architectural coverage (from Phase 3 gaps)
- Full chain complete (COVERED): [N/total] ([%])
---
@@ -0,0 +1,85 @@
# /architecture-review — Phase 4: Cross-ADR Conflict Detection
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 4: Cross-ADR Conflict Detection
Compare every ADR against every other ADR to detect contradictions. A conflict
exists when:
- **Data ownership conflict**: Two ADRs claim exclusive ownership of the same data
- **Integration contract conflict**: ADR-A assumes System X has interface Y, but
ADR-B defines System X with a different interface
- **Performance budget conflict**: ADR-A allocates N ms to physics, ADR-B allocates
N ms to AI, together they exceed the total frame budget
- **Dependency cycle**: ADR-A says System X initialises before Y; ADR-B says Y
initialises before X
- **Architecture pattern conflict**: ADR-A uses event-driven communication for a
subsystem; ADR-B uses direct function calls to the same subsystem
- **State management conflict**: Two ADRs define authority over the same game state
(e.g. both Combat ADR and Character ADR claim to own the health value)
For each conflict found:
```
## Conflict: [ADR-NNNN] vs [ADR-MMMM]
Type: [Data ownership / Integration / Performance / Dependency / Pattern / State]
ADR-NNNN claims: [...]
ADR-MMMM claims: [...]
Impact: [What breaks if both are implemented as written]
Resolution options:
1. [Option A]
2. [Option B]
```
### ADR Dependency Ordering
After conflict detection, analyse the dependency graph across all ADRs.
**Build the graph deterministically — do not trace it by hand:**
```
Bash: bash .claude/scripts/adr-dep-graph.sh
```
It collects every `Depends On` edge, runs Kahn's algorithm, and emits
`ADRS:` / `EDGES:` / `NO_DEPS_SECTION:` / `CYCLE:`. A model tracing A→B→C→A across
a dozen ADRs eventually misses an edge; the algorithm cannot. It reports
observations, not a verdict — you apply the meaning below.
**`NO_DEPS_SECTION` is load-bearing**: it makes "no cycles because the graph is
clean" distinguishable from "no cycles because half the ADRs declare no
dependencies". Report the second case as a structural gap, never as a clean graph.
Then interpret:
1. **Topological sort**: the emitted order — ADRs with no
dependencies come first (Foundation), ADRs that depend on those come next, etc.
2. **Flag unresolved dependencies**: cross the `EDGES:` list against the `## Status`
values already scanned in Phase 1b. If ADR-A depends on an ADR that is still
`Proposed` or does not exist, flag it:
```
⚠️ ADR-0005 depends on ADR-0002 — but ADR-0002 is still Proposed.
ADR-0005 cannot be safely implemented until ADR-0002 is Accepted.
```
3. **Cycle detection**: every `CYCLE:` line the script emitted is a
`DEPENDENCY CYCLE` — report each one. Do not re-derive them by hand:
```
🔴 DEPENDENCY CYCLE: ADR-0003 → ADR-0006 → ADR-0003
This cycle must be broken before either can be implemented.
```
4. **Output recommended implementation order**:
```
### Recommended ADR Implementation Order (topologically sorted)
Foundation (no dependencies):
1. ADR-0001: [title]
2. ADR-0003: [title]
Depends on Foundation:
3. ADR-0002: [title] (requires ADR-0001)
4. ADR-0005: [title] (requires ADR-0003)
Feature layer:
5. ADR-0004: [title] (requires ADR-0002, ADR-0005)
```
---
@@ -0,0 +1,113 @@
# /architecture-review — Phases 5 and 5b: Engine Cross-Check and Design Revision Flags
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 5: Engine Compatibility Cross-Check
**In this file:**
- Version Consistency
- Post-Cutoff API Consistency
- Deprecated API Check
- Missing Engine Compatibility Sections
- Engine Specialist Consultation
Across all ADRs, check for engine consistency:
### Version Consistency
- Do all ADRs that mention an engine version agree on the same version?
- If any ADR was written for an older engine version, flag it as potentially stale
### Post-Cutoff API Consistency
- Collect all "Post-Cutoff APIs Used" fields from all ADRs
- For each, verify against the relevant module reference doc
- Check that no two ADRs make contradictory assumptions about the same post-cutoff API
### Deprecated API Check
- Grep all ADRs for API names listed in `deprecated-apis.md`
- Flag any ADR referencing a deprecated API
### Missing Engine Compatibility Sections
- List all ADRs that are missing the Engine Compatibility section entirely
- These are blind spots — their engine assumptions are unknown
Output format:
```
### Engine Audit Results
Engine: [name + version]
ADRs with Engine Compatibility section: X / Y total
Deprecated API References:
- ADR-0002: uses [deprecated API] — deprecated since [version]
Stale Version References:
- ADR-0001: written for [older version] — current project version is [version]
Post-Cutoff API Conflicts:
- ADR-0004 and ADR-0007 both use [API] with incompatible assumptions
```
---
### Engine Specialist Consultation
After completing the engine audit above, spawn the **primary engine specialist** via `Agent` for a domain-expert second opinion:
- Resolve the primary specialist: `<engine>-specialist` derived from `engine.name` in `project.yaml` (Godot→`godot-specialist`, Unity→`unity-specialist`, Unreal→`unreal-specialist`); if `engine.name` is absent or empty, read the Primary line of the `## Engine Specialists` section in `.claude/docs/technical-preferences.md`
- If no engine is configured (neither source yields an engine), skip this consultation **Record ``Engine validation: NOT ASSESSED — no engine configured (`engine.name` unset in `project.yaml`)`` in this run's output.** A skipped check that says nothing is indistinguishable from a check that passed; the reader cannot tell engine guidance was never sought.
- Spawn `subagent_type: [primary specialist]` with: all ADRs that contain engine-specific decisions or `Post-Cutoff APIs Used` fields, the engine reference docs, and the Phase 5 audit findings. Ask them to:
1. Confirm or challenge each audit finding — specialists may know of engine nuances not captured in the reference docs
2. Identify engine-specific anti-patterns in the ADRs that the audit may have missed (e.g., using the wrong Godot node type, Unity component coupling, Unreal subsystem misuse)
3. Flag ADRs that make assumptions about engine behaviour that differ from the actual pinned version
Incorporate additional findings under `### Engine Specialist Findings` in the Phase 5 output. These feed into the final verdict — specialist-identified issues carry the same weight as audit-identified issues.
---
## Phase 5b: Design Revision Flags (Architecture → GDD Feedback)
For each **HIGH RISK engine finding** from Phase 5, check whether any GDD makes an
assumption that the verified engine reality contradicts.
Specific cases to check:
1. **Post-cutoff API behaviour differs from training-data assumptions**: If an ADR
records a verified API behaviour that differs from the default LLM assumption,
check all GDDs that reference the related system. Look for design rules written
around the old (assumed) behaviour.
2. **Known engine limitations in ADRs**: If an ADR records a known engine limitation
(e.g. "Jolt ignores HingeJoint3D damp", "D3D12 is now the default backend"), check
GDDs that design mechanics around the affected feature.
3. **Deprecated API conflicts**: If Phase 5 flagged a deprecated API used in an ADR,
check whether any GDD contains mechanics that assume the deprecated API's behaviour.
For each conflict found, record it in the GDD Revision Flags table:
```
### GDD Revision Flags (Architecture → Design Feedback)
These GDD assumptions conflict with verified engine behaviour or accepted ADRs.
The GDD should be revised before its system enters implementation.
| GDD | Assumption | Reality (from ADR/engine-reference) | Action |
|-----|-----------|--------------------------------------|--------|
| combat.md | "Use HingeJoint3D damp for weapon recoil" | Jolt ignores damp — ADR-0003 | Revise GDD |
```
If no revision flags are found, write: "No GDD revision flags — all GDD assumptions
are consistent with verified engine behaviour."
Before asking, display the proposed change inline — show the current systems-index row for each flagged GDD and the proposed updated row side by side so the user can see exactly what will change.
Then use `AskUserQuestion`:
- "I found [N] GDD revision flag(s). May I update the systems index?"
- [A] Yes — apply all [N] updates to the systems index now
- [B] Show me the full diff first, then ask again
- [C] No — leave the systems index unchanged for now
If [A]: apply the updates. Status field must be exactly `Needs Revision` — no parentheticals
(other skills match that exact string and parentheticals break the match).
If [B]: display the complete proposed systems-index section, then re-ask with `AskUserQuestion`.
---
@@ -0,0 +1,25 @@
# /architecture-review — Phase 6: Architecture Document Coverage
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 6: Architecture Document Coverage
**If `docs/architecture/architecture.md` does not exist, say so in the report** —
`Architecture document coverage: NOT ASSESSED — no docs/architecture/architecture.md`
— and carry it into the Phase 7 verdict per the trigger list below. Phase 5
already models this for the engine consultation (*"A skipped check that says
nothing is indistinguishable from a check that passed"*); this phase is the one
that did not. Silently producing no Phase 6 findings reads as an architecture
document that was checked and found clean, which is the opposite of what
happened.
If it exists, validate it against GDDs:
- Does every system from `systems-index.md` appear in the architecture layers?
- Does the data flow section cover all cross-system communication defined in GDDs?
- Do the API boundaries support all integration requirements from GDDs?
- Are there systems in the architecture doc that have no corresponding GDD
(orphaned architecture)?
---
@@ -0,0 +1,93 @@
# /architecture-review — Phase 7: Output the Review Report
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 7: Output the Review Report
```
## Architecture Review Report
Date: [date]
Engine: [name + version]
GDDs Reviewed: [N]
ADRs Reviewed: [M]
[output of: Bash: bash .claude/scripts/review-receipts.sh hash docs/architecture/adr-*.md design/gdd/*.md
— one Reviewed-Content-Hash line per file reviewed; Phase 1a's freshness
check reads these on the next run to skip or scope an unchanged re-review]
---
### Traceability Summary
Total requirements: [N]
✅ Covered: [X]
⚠️ Partial: [Y]
❌ Gaps: [Z]
### Coverage Gaps (no ADR exists)
For each gap:
❌ TR-[id]: [GDD] → [system] → [requirement]
Suggested ADR: "/architecture-decision [suggested title]"
Domain: [Physics/Rendering/etc]
Engine Risk: [LOW/MEDIUM/HIGH]
### Cross-ADR Conflicts
[List all conflicts from Phase 4]
### ADR Dependency Order
[Topologically sorted implementation order from Phase 4 — dependency ordering section]
[Unresolved dependencies and cycles if any]
### GDD Revision Flags
[GDD assumptions that conflict with verified engine behaviour — from Phase 5b]
[Or: "None — all GDD assumptions consistent with verified engine behaviour"]
### Engine Compatibility Issues
[List all engine issues from Phase 5]
### Architecture Document Coverage
[List missing systems and orphaned architecture from Phase 6]
---
### Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
PASS: All requirements covered by **Accepted** ADRs, no conflicts, engine consistent
NOT ASSESSED: The review could not be performed over its stated scope — name why
CONCERNS: Some gaps, partial coverage, or coverage resting on `Proposed` ADRs,
but no blocking conflicts
FAIL: Critical gaps (Foundation/Core layer requirements uncovered),
or blocking cross-ADR conflicts detected
**`NOT ASSESSED` ranks above PASS and below CONCERNS and FAIL.** Emit it when:
- **No ADRs exist, or none could be read.** Zero requirements traced is not full
coverage — it is an untraced architecture, and a matrix of `❌ Gap` rows at
least says so while an empty matrix says nothing.
- **The requirement source is missing** — no `tr-registry.yaml` and no GDD
requirements to trace *from*. A review with no left-hand column cannot report
coverage; it can only report that it had nothing to compare.
- **An ADR is unreadable or has no `## Status`**, so its rows are `❓` and their
coverage is unknown rather than absent.
- **Phase 6 could not run** — no `docs/architecture/architecture.md`. It must
appear as a named `NOT ASSESSED` **line item** in the report rather than as
absent findings. ADR traceability can still be complete, so a CONCERNS or FAIL
finding elsewhere still stands; but in `full` mode, whose scope includes
Phase 6, the verdict cannot be PASS — a review that could not look at part of
its scope has not shown that part is sound, so it is NOT ASSESSED.
- **No engine is configured** (`full` and `engine` modes) — Phase 5 has no pinned
engine reference to audit the ADRs against, and the specialist consultation was
skipped. Record the `Engine validation: NOT ASSESSED` line item; like Phase 6
above, it keeps the verdict from PASS.
Do not resolve any of these to PASS on the grounds that no gap was *found*. No
gap was looked for.
### Blocking Issues (must resolve before PASS)
[List items that must be resolved — FAIL verdict only]
### Required ADRs
[Prioritised list of ADRs to create, most foundational first]
```
---
@@ -0,0 +1,172 @@
# /architecture-review — Phase 8: Write and Update Traceability Index
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 8: Write and Update Traceability Index
**In this file:**
- RTM Output (rtm mode only)
- TR Registry Update
- Reflexion Log Update
- Session State Update
Use `AskUserQuestion` for the write approval:
- "Review complete. What would you like to write?"
- [A] Write all three files — review report (`docs/architecture/architecture-review-[date].md`), traceability index (`docs/architecture/requirements-traceability.md`), TR registry (`docs/architecture/tr-registry.yaml`)
- [B] Write review report only — `docs/architecture/architecture-review-[date].md`
- [C] Don't write anything yet — I need to review the findings first
When Phase 4 found a 🔴 conflict and `docs/consistency-failures.md` exists, name
that file in option [A] as well — "…and append [N] conflict entr(y/ies) to
`docs/consistency-failures.md`". Only [A] appends there (see Reflexion Log
Update); [B] writes the report and nothing else.
### RTM Output (rtm mode only)
For `rtm` mode, use `AskUserQuestion`:
- "May I write the full Requirements Traceability Matrix?"
- [A] Yes — write to `docs/architecture/requirements-traceability.md`
- [B] Not yet — show me the full RTM data first, then ask again
RTM file format:
```markdown
# Requirements Traceability Matrix (RTM)
> Last Updated: [date]
> Mode: /architecture-review rtm
> Coverage: [N]% full chain complete (GDD → ADR → Story → Test)
## How to read this matrix
| Column | Meaning |
|--------|---------|
| TR-ID | Stable requirement ID from tr-registry.yaml |
| GDD | Source design document |
| ADR | Architectural decision governing implementation |
| Story | Story file that implements this requirement |
| Test File | Automated test file path |
| Test Status | COVERED / MISSING / NONE / NO STORY |
## Full Traceability Matrix
| TR-ID | GDD | Requirement | ADR | Story | Test File | Status |
|-------|-----|-------------|-----|-------|-----------|--------|
[Full matrix rows from Phase 3b]
## Coverage Summary
| Status | Count | % |
|--------|-------|---|
| COVERED — full chain complete | [N] | [%] |
| MISSING test — story exists, no test | [N] | [%] |
| NO STORY — ADR exists, not yet implemented | [N] | [%] |
| NO ADR — architectural gap | [N] | [%] |
| **Total requirements** | **[N]** | **100%** |
## Uncovered Requirements (Priority Fix List)
Requirements where the full chain is broken, prioritised by layer:
### Foundation layer gaps
[list with suggested action per gap]
### Core layer gaps
[list]
### Feature / Presentation layer gaps
[list — lower priority]
## History
| Date | Full Chain % | Notes |
|------|-------------|-------|
| [date] | [%] | Initial RTM |
```
### TR Registry Update
Also ask: "May I update `docs/architecture/tr-registry.yaml` with new requirement
IDs from this review?"
If yes, read the current `docs/architecture/tr-registry.yaml` again first:
the review read it at the start, and another skill or session may have changed
it since. Build the update from that fresh read, never from the earlier copy,
and keep every entry already in it. Then:
- **Append** any new TR-IDs that weren't in the registry before this review
- **Update** `requirement` text and `revised` date for any entries whose GDD
wording changed (ID stays the same)
- **Mark** `status: deprecated` for any registry entries whose GDD requirement
no longer exists (confirm with user before marking deprecated)
- **Mark** `status: "superseded-by: TR-[system]-NNN"` for an entry whose
requirement was split or replaced, naming the new TR-ID(s). Keep the quotes:
unquoted, the second colon makes the file invalid YAML
- **Never** renumber or delete existing entries
- Update the `last_updated` and `version` fields at the top
This ensures all future story files can reference stable TR-IDs that persist
across every subsequent architecture review.
### Reflexion Log Update
When the user chose Phase 8's [A] — the option that named this file — append
any 🔴 CONFLICT entries found in Phase 4 to `docs/consistency-failures.md` (if
the file exists), after writing the review report:
```markdown
### [YYYY-MM-DD] — /architecture-review — 🔴 CONFLICT
**Domain**: Architecture / [specific domain e.g. State Ownership, Performance]
**Documents involved**: [ADR-NNNN] vs [ADR-MMMM]
**What happened**: [specific conflict — what each ADR claims]
**Resolution**: [how it was or should be resolved]
**Pattern**: [generalised lesson for future ADR authors in this domain]
```
Only append CONFLICT entries — do not log GAP entries (missing ADRs are expected
before the architecture is complete). Do not create the file if missing — only
append when it already exists.
### Session State Update
After writing all approved files, silently append to
`production/session-state/active.md`:
## Session Extract — /architecture-review [date]
- Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
- Requirements: [N] total — [X] covered, [Y] partial, [Z] gaps
- New TR-IDs registered: [N, or "None"]
- GDD revision flags: [comma-separated GDD names, or "None"]
- Top ADR gaps: [top 3 gap titles from the report, or "None"]
- Report: docs/architecture/architecture-review-[date].md
If `active.md` does not exist, create it with this block as the initial content.
Confirm in conversation: "Session state updated."
The traceability index — written to `docs/architecture/requirements-traceability.md`,
the path `/propagate-design-change` and the Pre-Production gate read; `rtm` mode
later extends the same file with story and test columns — uses this format:
```markdown
# Architecture Traceability Index
Last Updated: [date]
Engine: [name + version]
## Coverage Summary
- Total requirements: [N]
- Covered: [X] ([%])
- Partial: [Y]
- Gaps: [Z]
## Full Matrix
[Complete traceability matrix from Phase 3]
## Known Gaps
[All ❌ items with suggested ADRs]
## Superseded Requirements
[Requirements whose GDD was changed after the ADR was written]
```
---
@@ -0,0 +1,35 @@
# /architecture-review — Phase 9: Handoff
> Part of `/architecture-review`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 9: Handoff
After completing the review and writing approved files, present:
1. **Immediate actions**: List the top 3 ADRs to create (highest-impact gaps first,
Foundation layer before Feature layer)
2. **Pre-gate checklist**: Check whether these exist via Glob and mark each ✅ or ❌:
- the engine's test root — `tests/unit/` and `tests/integration/` (Godot), `Assets/Tests/EditMode/` and `Assets/Tests/PlayMode/` (Unity), `Source/<Module>/Private/Tests/` (Unreal) — if ❌: run `/test-setup`
- `.github/workflows/tests.yml` — if ❌: run `/test-setup`
- `design/accessibility-requirements.md` — if ❌: run `/ux-design`
- `design/ux/interaction-patterns.md` — if ❌: run `/ux-design`
Present ❌ items as required steps before gate-check. Do not offer `/gate-check`
as an option if any item is ❌ — offer the missing skill to run instead.
3. **Rerun trigger**: "Re-run `/architecture-review` after each new ADR is written
to verify coverage improves"
Then close with `AskUserQuestion` tailored to the pre-gate checklist state:
- If ADR gaps remain or any pre-gate item is ❌:
- "Architecture review complete. What would you like to do next?"
- [A] Write a missing ADR — open a fresh session and run `/architecture-decision [system]`
- [B] Run `/test-setup` — required before gate-check (only show if test infrastructure is ❌)
- [C] Run `/ux-design` — required before gate-check (only show if UX/accessibility files are ❌)
- [D] Stop here for this session
- If all pre-gate checklist items are ✅ and no blocking ADR gaps remain:
- "Architecture review complete. All pre-gate items confirmed. What would you like to do next?"
- [A] Run `/gate-check pre-production`
- [B] Write a missing ADR — open a fresh session and run `/architecture-decision [system]`
- [C] Stop here for this session
---
+2
View File
@@ -12,6 +12,8 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode`. No block →
defaults in `.claude/docs/config-resolution.md`.
# Art Bible
## Phase 0: Parse Arguments and Context Check
+6 -5
View File
@@ -8,6 +8,8 @@ model: sonnet
# Read-only diagnostic skill — no specialist agent delegation needed
---
# Asset Audit
## Measuring file sizes and formats requires Bash
This skill's report asks for **file sizes against budgets**, **texture dimensions**
@@ -43,11 +45,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
+2
View File
@@ -9,6 +9,8 @@ model: sonnet
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys review_mode,automation`
# Asset Spec
If no argument is provided, check whether `design/assets/entity-inventory.md` exists:
+6 -5
View File
@@ -9,6 +9,8 @@ model: sonnet
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation`
# Balance Check
Every `AskUserQuestion` call follows `.claude/docs/automation-modes.md`
@@ -33,11 +35,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
+2
View File
@@ -12,6 +12,8 @@ model: sonnet
Resolved above — use as-is. No block → defaults in
`.claude/docs/config-resolution.md`.
# Brainstorm
`--review` overrides `review_mode`; store it for all gate spawns this run. See
`.claude/docs/director-gates.md` for the full check pattern. Individual gate definitions live in `.claude/docs/director-gates/[gate-id].md` — the spawned agent reads its own gate file; do not read it in the parent session.
+2
View File
@@ -15,6 +15,8 @@ every file write follows `.claude/docs/automation-modes.md`
(collaborative asks always · guided major-only · autonomous logs and proceeds;
`automation_always_ask` categories always prompt).
# Bug Report
## Phase 1: Parse Arguments
Determine the mode from the argument:
+2 -2
View File
@@ -7,7 +7,7 @@ allowed-tools: Read, Glob, Grep, Write, Edit, Bash(bash "*/.claude/skills/bug-tr
model: sonnet
---
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation`
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow`
**Automation mode**: Resolve `modes.automation` (`project.local.yaml` →
`project.yaml` → default `collaborative`). Every `AskUserQuestion` call and
@@ -77,7 +77,7 @@ Read the most recently modified file in `production/sprints/` to understand:
- Stories in scope (for assignment target)
- Sprint capacity constraints (if noted)
If no sprint file exists: note "No sprint plan found — assigning to backlog only."
If no sprint file exists: note "No sprint plan found — assigning to backlog only." At `workflow: minimal` there are no sprints by design — say that instead, and name the P1 bugs as the next fixes, ahead of the next story in the brief's build order.
### Step 2c — Load severity reference
+2
View File
@@ -15,6 +15,8 @@ every file write follows `.claude/docs/automation-modes.md`
(collaborative asks always · guided major-only · autonomous logs and proceeds;
`automation_always_ask` categories always prompt).
# Changelog
## Recent History
Recent commits:
+6 -5
View File
@@ -9,6 +9,8 @@ model: sonnet
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation`
# Code Review
Every `AskUserQuestion` call follows `.claude/docs/automation-modes.md`
@@ -33,11 +35,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
@@ -271,6 +271,12 @@ Verdict: PASS | CONFLICTS FOUND | NOT ASSESSED
## Phase 6: Registry Corrections
**Re-read before you write.** Phase 1 read the registry before the scans, and
another skill or session may have changed it since. Before each Edit, read the
current `design/registry/entities.yaml`, find the entry in its section, and
anchor the Edit on the entry's current text, never on what Phase 1 saw. Append
a new entry after the last existing entry of its section.
If stale registry entries were found, ask:
> "May I update `design/registry/entities.yaml` to fix the [N] stale entries?"
+6 -5
View File
@@ -17,6 +17,8 @@ every file write follows `.claude/docs/automation-modes.md`
Resolved above — use as-is. No block → defaults in `.claude/docs/config-resolution.md`.
# Content Audit
> This skill declares tier-dependent behaviour ("audit only specs in the required
> sections"), which is unreachable unless the tier is actually resolved — without
> it the skill applies whatever tier it assumed. Resolve `modes.workflow` before
@@ -59,11 +61,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
+9 -478
View File
@@ -12,7 +12,6 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode`. No block →
defaults in `.claude/docs/config-resolution.md`.
# Create Architecture
This skill produces `docs/architecture/architecture.md` — the master architecture
@@ -22,10 +21,8 @@ It sits between design and implementation, and must exist before sprint planning
**Distinct from `/architecture-decision`**: ADRs record individual point decisions.
This skill creates the whole-system blueprint that gives ADRs their context.
See `.claude/docs/director-gates.md` for the full check pattern. Individual gate definitions live in `.claude/docs/director-gates/[gate-id].md` — the spawned agent reads its own gate file; do not read it in the parent session.
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).
@@ -54,505 +51,39 @@ considered per layer. Apply it to every section you author.
## Phase 0: Load All Context
Before anything else, load the full project context in this order:
### 0a. Engine Context (Critical)
Read the four project-wide engine documents in full — they are small, and every
part of each is used:
1. `docs/engine-reference/[engine]/VERSION.md`
→ Extract: engine name, version, LLM cutoff, post-cutoff risk levels
2. `docs/engine-reference/[engine]/breaking-changes.md`
→ Extract: all HIGH and MEDIUM risk changes
3. `docs/engine-reference/[engine]/deprecated-apis.md`
→ Extract: APIs to avoid
4. `docs/engine-reference/[engine]/current-best-practices.md`
→ Extract: post-cutoff best practices that differ from training data
Then read **only the module docs whose domain this game actually uses** —
not the whole `modules/` directory:
5. `docs/engine-reference/[engine]/modules/` — glob it to establish what exists,
then match against the domains present in `design/gdd/systems-index.md`
(the same domain vocabulary the ADR template uses: Physics, Rendering, UI,
Audio, Navigation, Animation, Networking, Core, Input). Read the matching
modules; skip the rest.
→ Extract: current API patterns per domain
A game with no multiplayer system does not need the networking module loaded
to write its architecture, and loading it costs the same as one that does.
**If the domain match is ambiguous, read the module** — a missed engine
constraint is far more expensive here than a redundant read, because this
phase is where those constraints get baked into the architecture.
If no engine is configured, stop and prompt:
> "No engine is configured. Run `/setup-engine` first. Architecture cannot be
> written without knowing which engine and version you are targeting."
### 0b. Design Context + Technical Requirements Extraction
Load the approved design documents and extract technical requirements from each:
1. `design/gdd/game-concept.md` — game pillars, genre, core loop
2. `design/gdd/systems-index.md` — all systems, dependencies, priority tiers
**Check both exist before reading either. Neither is optional here, and both
need an absence branch** — §0a stops for an unconfigured engine, and these two
matter just as much:
- **`systems-index.md` absent** — stop:
> "No systems index found. Run `/map-systems` first. An architecture written
> without it invents layers for systems nobody mapped, and every ADR, epic and
> story downstream inherits that invention."
At `minimal` the index is not required (§ tier note above) — say so and proceed
from the brief instead.
- **`game-concept.md` absent** — at `standard`/`full`, stop and point at
`/brainstorm`. At `minimal`, read `design/game-brief.md` in its place; if that
is absent too, stop — there is no design record to architect against.
- **Either present but empty or still template placeholders** — treat as absent.
Present-but-empty is the case that most looks like present.
Do not proceed on a partial read and note it later. This phase is where design
assumptions get baked into ADRs, and an assumption made here is re-derived by
everything downstream rather than re-checked.
3. Project config — `naming.*` and `performance.*` from `project.yaml` (for any
key absent or empty, fall back to `.claude/docs/technical-preferences.md`);
allowed libraries and forbidden patterns from
`.claude/docs/technical-preferences.md` (not migrated to project.yaml)
4. **Every GDD in `design/gdd/`** — extract technical requirements from the
sections that carry them, **not from whole files**. Establish the denominator
first (glob `design/gdd/*.md`, count **N**), then:
```
Grep pattern="^## (Detailed Rules|Detailed Design|Formulas|Dependencies|Tuning Knobs|Acceptance Criteria)" glob="design/gdd/*.md" output_mode="content" -A 40
```
Overview and Player Fantasy are narrative and imply no architecture; the
scanned set is where rules, numbers, and cross-system contracts live. Accept
either `## Detailed Rules` or `## Detailed Design` — the design standard and
the GDD template disagree on the name and they denote the same section.
Full-read a GDD when it matched **zero** sections (it predates the template —
a zero-match means "unstructured", never "no requirements") or when a scanned
section refers to material outside itself. **Never treat an absent section as
an absent requirement**: report any GDD that contributed nothing, rather than
letting it drop silently out of the baseline below.
For each, extract:
- Data structures implied by the game rules
- Performance constraints stated or implied
- Engine capabilities the system requires
- Cross-system communication patterns (what talks to what, how)
- State that must persist (save/load implications)
- Threading or timing requirements
Build a **Technical Requirements Baseline** — a flat list of all extracted
requirements across all GDDs, numbered `TR-[gdd-slug]-[NNN]`. This is the
complete set of what the architecture must cover. Present it as:
```
## Technical Requirements Baseline
Extracted from [N] GDDs | [X] total requirements
| Req ID | GDD | System | Requirement | Domain |
|--------|-----|--------|-------------|--------|
| TR-combat-001 | combat.md | Combat | Hitbox detection per-frame | Physics |
| TR-combat-002 | combat.md | Combat | Combo state machine | Core |
| TR-inventory-001 | inventory.md | Inventory | Item persistence | Save/Load |
```
This baseline feeds into every subsequent phase. No GDD requirement should be
left without an architectural decision to support it by the end of this session.
### 0c. Existing Architecture Decisions
To learn **what has already been decided and in which domain**, scan the ADR
headers — do not full-read every ADR to produce a list of numbers and domains:
```
Grep pattern="^## (Status|Summary)" glob="docs/architecture/adr-*.md" output_mode="content" -A 4
Grep pattern="\*\*Domain\*\*" glob="docs/architecture/adr-*.md" output_mode="content"
```
`## Summary` (a 2-sentence what-and-why) plus `## Status` and the Engine
Compatibility `Domain` field are exactly "what was decided and its domain". List
the ADRs found, their status, and their domains from the scan. Full-read a
specific ADR only when a new decision this session would collide with it and you
need its reasoning — not to build the inventory.
### 0d. Generate Knowledge Gap Inventory
Before proceeding, display a structured summary:
```
## Engine Knowledge Gap Inventory
Engine: [name + version]
LLM Training Covers: up to approximately [version]
Post-Cutoff Versions: [list]
### HIGH RISK Domains (must verify against engine reference before deciding)
- [Domain]: [Key changes]
### MEDIUM RISK Domains (verify key APIs)
- [Domain]: [Key changes]
### LOW RISK Domains (in training data, likely reliable)
- [Domain]: [no significant post-cutoff changes]
### Systems from GDD that touch HIGH/MEDIUM risk domains:
- [GDD system name] → [domain] → [risk level]
```
Use `AskUserQuestion`:
- Prompt: "One or more engine domains are HIGH RISK — the LLM's knowledge may be unreliable for these areas. Architectural recommendations in these domains should be cross-referenced with the engine docs before being acted on. How would you like to proceed?"
- Options:
- `[A] Proceed — flag HIGH RISK domains throughout the output`
- `[B] Let me check the engine reference first — pause here`
- `[C] Show me which domains are HIGH RISK and why`
### 0e. Existing Architecture Document
Glob `docs/architecture/architecture.md`. If it exists, this run updates it —
it never replaces it unasked. Read its `## Document Status` block and its `##`
headings, then use `AskUserQuestion`:
- Prompt: "An architecture document already exists (v[N], [last updated]). What should this run do?"
- Options: `[A] Update chosen sections in place` / `[B] Rewrite the whole document — replaces the existing file` / `[C] Stop`
On `[A]`, ask which sections. Phases 1–6 author only those and say which they
skipped; Phase 7 replaces just those sections and raises `Version` to N+1,
leaving every other section as it is. `[B]` runs the full walkthrough, and
Phase 7's ask says it replaces the existing file.
A focus-area argument (`layers`, `data-flow`, `api-boundaries`, `adr-audit`)
is `[A]` with that one section chosen: it runs only its phase (1, 3, 4 or 5),
and Phase 7 writes that section. Phase 7b still runs on the updated document —
an update is reviewed like a first draft, at the review modes that review one. With no existing document there is nothing to
update — say so, and offer the full walkthrough instead.
---
**Read `references/0-load-context.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 1: System Layer Mapping
Map every system from `systems-index.md` into an architecture layer. The standard
game architecture layers are:
```
┌─────────────────────────────────────────────┐
│ PRESENTATION LAYER │ ← UI, HUD, menus, VFX, audio
├─────────────────────────────────────────────┤
│ FEATURE LAYER │ ← gameplay systems, AI, quests
├─────────────────────────────────────────────┤
│ CORE LAYER │ ← physics, input, combat, movement
├─────────────────────────────────────────────┤
│ FOUNDATION LAYER │ ← engine integration, save/load,
│ │ scene management, event bus
├─────────────────────────────────────────────┤
│ PLATFORM LAYER │ ← OS, hardware, engine API surface
└─────────────────────────────────────────────┘
```
For each GDD system, ask:
- Which layer does it belong to?
- What are its module boundaries?
- What does it own exclusively? (data, state, behaviour)
Present the proposed layer assignment and ask for approval before proceeding to
the next section. Record the approved layer map in
`production/session-state/active.md`; it goes into the document at Phase 7.
**Engine awareness check**: For each system assigned to the Core and Foundation
layers, flag if it touches a HIGH or MEDIUM risk engine domain. Show the relevant
engine reference excerpt inline.
---
**Read `references/1-layers.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 2: Module Ownership Map
For each module defined in Phase 1, define ownership:
- **Owns**: what data and state this module is solely responsible for
- **Exposes**: what other modules may read or call
- **Consumes**: what it reads from other modules
- **Engine APIs used**: which specific engine classes/nodes/signals this module
calls directly (with version and risk level noted)
Format as a table per layer, then as an ASCII dependency diagram.
**Engine awareness check**: For every engine API listed, verify against the
relevant module reference doc. If an API is post-cutoff, flag it:
```
⚠️ [ClassName.method()] — Godot 4.6 (post-cutoff, HIGH risk)
Verified against: docs/engine-reference/godot/modules/[domain].md
Behaviour confirmed: [yes / NEEDS VERIFICATION]
```
Get user approval on the ownership map, then record it in
`production/session-state/active.md`; it is written at Phase 7.
---
**Read `references/2-module-ownership.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 3: Data Flow
Define how data moves between modules during key game scenarios. Cover at minimum:
1. **Frame update path**: Input → Core systems → State → Rendering
2. **Event/signal path**: How systems communicate without tight coupling
3. **Save/load path**: What state is serialised, which module owns serialisation
4. **Initialisation order**: Which modules must boot before others
Use ASCII sequence diagrams where helpful. For each data flow:
- Name the data being transferred
- Identify the producer and consumer
- State whether this is synchronous call, signal/event, or shared state
- Flag any data flows that cross thread boundaries
Get user approval on each scenario, then record it in
`production/session-state/active.md`; it is written at Phase 7.
---
**Read `references/3-data-flow.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 4: API Boundaries
Define the public contracts between modules. For each boundary:
- What is the interface a module exposes to the rest of the system?
- What are the entry points (functions/signals/properties)?
- What invariants must callers respect?
- What must the module guarantee to callers?
Write in pseudocode or the project's actual language (from technical preferences).
These become the contracts programmers implement against.
**Engine awareness check**: If any interface uses engine-specific types (e.g.
`Node`, `Resource`, `Signal` in Godot), flag the version and verify the type
exists and has not changed signature in the target engine version.
Get user approval on the API boundaries, then record them in
`production/session-state/active.md`; they are written at Phase 7.
---
**Read `references/4-api-boundaries.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 5: ADR Audit + Traceability Check
Review all existing ADRs from Phase 0c against both the architecture built in
Phases 1-4 AND the Technical Requirements Baseline from Phase 0b.
### ADR Quality Check
For each ADR:
- [ ] Does it have an Engine Compatibility section?
- [ ] Is the engine version recorded?
- [ ] Are post-cutoff APIs flagged?
- [ ] Does it have a "GDD Requirements Addressed" section?
- [ ] Does it conflict with the layer/ownership decisions made in this session?
- [ ] Is it still valid for the pinned engine version?
| ADR | Engine Compat | Version | GDD Linkage | Conflicts | Valid |
|-----|--------------|---------|-------------|-----------|-------|
| ADR-0001: [title] | ✅/❌ | ✅/❌ | ✅/❌ | None/[conflict] | ✅/⚠️ |
### Traceability Coverage Check
Map every requirement from the Technical Requirements Baseline to existing ADRs.
For each requirement, check if any ADR's "GDD Requirements Addressed" section
or decision text covers it:
| Req ID | Requirement | ADR Coverage | Status |
|--------|-------------|--------------|--------|
| TR-combat-001 | Hitbox detection per-frame | ADR-0003 | ✅ |
| TR-combat-002 | Combo state machine | — | ❌ GAP |
Count: X covered, Y gaps. For each gap, it becomes a **Required New ADR**.
### Required New ADRs
List all decisions made during this architecture session (Phases 1-4) that do
not yet have a corresponding ADR, PLUS all uncovered Technical Requirements.
Group by layer — Foundation first:
**Foundation Layer (must create before any coding):**
- `/architecture-decision [title]` → covers: TR-[id], TR-[id]
**Core Layer:**
- `/architecture-decision [title]` → covers: TR-[id]
---
**Read `references/5-adr-audit.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 6: Missing ADR List
Based on the full architecture, produce a complete list of ADRs that should exist
but don't yet. Group by priority:
**Must have before coding starts (Foundation & Core decisions):**
- [e.g. "Scene management and scene loading strategy"]
- [e.g. "Event bus vs direct signal architecture"]
**Should have before the relevant system is built:**
- [e.g. "Inventory serialisation format"]
**Can defer to implementation:**
- [e.g. "Specific shader technique for water"]
---
**Read `references/6-missing-adrs.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 7: Write the Master Architecture Document
Once all sections are approved, write the complete document to
`docs/architecture/architecture.md`.
In an update (Phase 0e `[A]`, or a focus-area argument), write only the chosen
sections instead, replacing each in place with `Edit`, and raise `Version`; the
ask below then names those sections and the version change.
Display a one-paragraph summary of what the document will contain (layers, modules, data flows, ADR gaps). Then use `AskUserQuestion`:
- "All sections approved. May I write the master architecture document?"
- [A] Yes — write to `docs/architecture/architecture.md` now
- [B] Show me the full draft inline first, then ask again
- [C] Not yet — I have more changes to discuss
The document structure:
```markdown
# [Game Name] — Master Architecture
## Document Status
- Version: [N]
- Last Updated: [date]
- Engine: [name + version]
- GDDs Covered: [list]
- ADRs Referenced: [list]
## Engine Knowledge Gap Summary
[Condensed from Phase 0d inventory — HIGH/MEDIUM risk domains and their implications]
## System Layer Map
[From Phase 1]
## Module Ownership
[From Phase 2]
## Data Flow
[From Phase 3]
## API Boundaries
[From Phase 4]
## ADR Audit
[From Phase 5]
## Required ADRs
[From Phase 6]
## Architecture Principles
[3-5 key principles that govern all technical decisions for this project,
derived from the game concept, GDDs, and technical preferences]
## Open Questions
[Decisions deferred — must be resolved before the relevant layer is built]
```
---
## Phase 7b: Technical Director Sign-Off + Lead Programmer Feasibility Review
After writing the master architecture document, perform an explicit sign-off before handoff.
**Review mode check** — apply before spawning either gate:
- `solo` → skip both. Note: "TD-ARCHITECTURE and LP-FEASIBILITY skipped — Solo mode." Go to Step 4 and record both as skipped, then Phase 8.
- `lean` → skip both (neither is a PHASE-GATE). Note: "TD-ARCHITECTURE and LP-FEASIBILITY skipped — Lean mode." Go to Step 4 and record both as skipped, then Phase 8.
- `full` → spawn both, in parallel.
**Step 1 — Spawn `technical-director` via `Agent` using gate TD-ARCHITECTURE (`.claude/docs/director-gates/td-architecture.md`):**
Pass: the architecture document path (`docs/architecture/architecture.md`), the Technical Requirements Baseline (TR-IDs and count), the ADR list with statuses, and the Engine Knowledge Gap Inventory from Phase 0d. Issue this call and Step 2's before waiting for either result.
**Step 2 — Spawn `lead-programmer` via `Agent` using gate LP-FEASIBILITY (`.claude/docs/director-gates/lp-feasibility.md`):**
Pass: architecture document path, technical requirements baseline summary, ADR list.
**Step 3 — Present both assessments to the user:**
Show the TD-ARCHITECTURE verdict (APPROVE / CONCERNS / REJECT) and the LP-FEASIBILITY verdict (FEASIBLE / CONCERNS / INFEASIBLE) side by side.
Use `AskUserQuestion` — "Technical Director and Lead Programmer have reviewed the architecture. How would you like to proceed?"
Options: `Accept — proceed to handoff` / `Revise flagged items first` / `Discuss specific concerns`.
If either verdict is REJECT or INFEASIBLE, do not offer `Accept` — the blockers are revised (or discussed) first.
`Revise flagged items first` re-drafts each flagged section and shows it for approval as in Phases 1–4; the revised document is then written once, through Phase 7's ask, and Step 4 records `REVISED after [verdict]`.
A `NOT ASSESSED` answer is never recorded as `APPROVE` or `FEASIBLE`: Step 4 records it with the input that was missing (`director-gates.md`).
**Step 4 — Record sign-off in the architecture document:**
Update the Document Status section:
```
- TD-ARCHITECTURE: [date] — APPROVE / CONCERNS (accepted) / REVISED after CONCERNS / REVISED after REJECT / NOT ASSESSED — [missing input] / skipped — [mode] mode
- LP-FEASIBILITY: [date] — FEASIBLE / CONCERNS (accepted) / REVISED after CONCERNS / REVISED after INFEASIBLE / NOT ASSESSED — [missing input] / skipped — [mode] mode
```
Show the proposed Document Status block inline, then use `AskUserQuestion`:
- "May I update the Document Status section with the sign-off results?"
- [A] Yes — apply to `docs/architecture/architecture.md`
- [B] Not yet — I want to revisit the concerns first
---
**Read `references/7-write.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 8: Handoff
**Step 1 — Update session state**: Write a summary to `production/session-state/active.md` covering: artifact written, TD/LP sign-off verdicts, any blockers, required ADRs remaining, and next step.
**Step 2 — Output the handoff** using exactly this template (no freeform prose, no rephrasing of section titles):
---
## Architecture Complete
`docs/architecture/architecture.md` v[N] — [TD-ARCHITECTURE: APPROVE / CONCERNS (accepted) / REVISED after CONCERNS / REVISED after REJECT / NOT ASSESSED / skipped — [mode] mode]. [One sentence on what the architecture covers.]
---
## Run These ADRs Next
**1. `/architecture-decision "[Title]"` → ADR-[XXXX]**
[One sentence: what it defines and what it unblocks.]
**2. `/architecture-decision "[Title]"` → ADR-[XXXX]**
[One sentence.]
**3. `/architecture-decision "[Title]"` → ADR-[XXXX]**
[One sentence.]
**Then:** `/architecture-review`, and `/create-control-manifest` once it passes and those ADRs are Accepted — it turns them into the layer rules manifest.
List top 3 from Phase 6 in priority order. If fewer than 3 remain, list only what's outstanding.
---
## Gate-Check Readiness
> **Required before `/gate-check pre-production`:**
> - [ ] Accept ADRs: [list Proposed ADR IDs that must be Accepted]
> - [ ] Write ADRs: [list ADR IDs that must still be written]
> - [ ] Run `/architecture-review` — writes the review report and the traceability index (`docs/architecture/requirements-traceability.md`) the gate reads
> - [ ] Run `/test-setup` — scaffolds `tests/unit/`, `tests/integration/`, CI workflow, and an example test file
> - [ ] Run `/ux-design` — creates `design/ux/interaction-patterns.md` and `design/accessibility-requirements.md`
>
> Run `/gate-check pre-production` when all boxes are checked.
If nothing is blocking, write instead:
> No blockers — run `/gate-check pre-production` now.
---
## Open Questions to Watch
| ID | Summary | Priority | Resolution Path |
|----|---------|----------|-----------------|
| QQ-XX | [short description] | High / Medium / Low | [ADR or system that resolves it] |
Omit this section entirely if there are no open QQs.
---
(End of handoff. Do not add trailing commentary after the closing rule.)
---
**Read `references/8-handoff.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Collaborative Protocol
@@ -0,0 +1,189 @@
# /create-architecture — Phase 0: Load All Context
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 0: Load All Context
**In this file:**
- 0a. Engine Context (Critical)
- 0b. Design Context + Technical Requirements Extraction
- 0c. Existing Architecture Decisions
- 0d. Generate Knowledge Gap Inventory
- 0e. Existing Architecture Document
Before anything else, load the full project context in this order:
### 0a. Engine Context (Critical)
Read the four project-wide engine documents in full — they are small, and every
part of each is used:
1. `docs/engine-reference/[engine]/VERSION.md`
→ Extract: engine name, version, LLM cutoff, post-cutoff risk levels
2. `docs/engine-reference/[engine]/breaking-changes.md`
→ Extract: all HIGH and MEDIUM risk changes
3. `docs/engine-reference/[engine]/deprecated-apis.md`
→ Extract: APIs to avoid
4. `docs/engine-reference/[engine]/current-best-practices.md`
→ Extract: post-cutoff best practices that differ from training data
Then read **only the module docs whose domain this game actually uses** —
not the whole `modules/` directory:
5. `docs/engine-reference/[engine]/modules/` — glob it to establish what exists,
then match against the domains present in `design/gdd/systems-index.md`
(the same domain vocabulary the ADR template uses: Physics, Rendering, UI,
Audio, Navigation, Animation, Networking, Core, Input). Read the matching
modules; skip the rest.
→ Extract: current API patterns per domain
A game with no multiplayer system does not need the networking module loaded
to write its architecture, and loading it costs the same as one that does.
**If the domain match is ambiguous, read the module** — a missed engine
constraint is far more expensive here than a redundant read, because this
phase is where those constraints get baked into the architecture.
If no engine is configured, stop and prompt:
> "No engine is configured. Run `/setup-engine` first. Architecture cannot be
> written without knowing which engine and version you are targeting."
### 0b. Design Context + Technical Requirements Extraction
Load the approved design documents and extract technical requirements from each:
1. `design/gdd/game-concept.md` — game pillars, genre, core loop
2. `design/gdd/systems-index.md` — all systems, dependencies, priority tiers
**Check both exist before reading either. Neither is optional here, and both
need an absence branch** — §0a stops for an unconfigured engine, and these two
matter just as much:
- **`systems-index.md` absent** — stop:
> "No systems index found. Run `/map-systems` first. An architecture written
> without it invents layers for systems nobody mapped, and every ADR, epic and
> story downstream inherits that invention."
At `minimal` the index is not required (§ tier note above) — say so and proceed
from the brief instead.
- **`game-concept.md` absent** — at `standard`/`full`, stop and point at
`/brainstorm`. At `minimal`, read `design/game-brief.md` in its place; if that
is absent too, stop — there is no design record to architect against.
- **Either present but empty or still template placeholders** — treat as absent.
Present-but-empty is the case that most looks like present.
Do not proceed on a partial read and note it later. This phase is where design
assumptions get baked into ADRs, and an assumption made here is re-derived by
everything downstream rather than re-checked.
3. Project config — `naming.*` and `performance.*` from `project.yaml` (for any
key absent or empty, fall back to `.claude/docs/technical-preferences.md`);
allowed libraries and forbidden patterns from
`.claude/docs/technical-preferences.md` (not migrated to project.yaml)
4. **Every GDD in `design/gdd/`** — extract technical requirements from the
sections that carry them, **not from whole files**. Establish the denominator
first (glob `design/gdd/*.md`, count **N**), then:
```
Grep pattern="^## (Detailed Rules|Detailed Design|Formulas|Dependencies|Tuning Knobs|Acceptance Criteria)" glob="design/gdd/*.md" output_mode="content" -A 40
```
Overview and Player Fantasy are narrative and imply no architecture; the
scanned set is where rules, numbers, and cross-system contracts live. Accept
either `## Detailed Rules` or `## Detailed Design` — the design standard and
the GDD template disagree on the name and they denote the same section.
Full-read a GDD when it matched **zero** sections (it predates the template —
a zero-match means "unstructured", never "no requirements") or when a scanned
section refers to material outside itself. **Never treat an absent section as
an absent requirement**: report any GDD that contributed nothing, rather than
letting it drop silently out of the baseline below.
For each, extract:
- Data structures implied by the game rules
- Performance constraints stated or implied
- Engine capabilities the system requires
- Cross-system communication patterns (what talks to what, how)
- State that must persist (save/load implications)
- Threading or timing requirements
Build a **Technical Requirements Baseline** — a flat list of all extracted
requirements across all GDDs, numbered `TR-[system]-[NNN]`, the TR registry's
ID format. This is the
complete set of what the architecture must cover. Present it as:
```
## Technical Requirements Baseline
Extracted from [N] GDDs | [X] total requirements
| Req ID | GDD | System | Requirement | Domain |
|--------|-----|--------|-------------|--------|
| TR-combat-001 | combat.md | Combat | Hitbox detection per-frame | Physics |
| TR-combat-002 | combat.md | Combat | Combo state machine | Core |
| TR-inventory-001 | inventory.md | Inventory | Item persistence | Save/Load |
```
This baseline feeds into every subsequent phase. No GDD requirement should be
left without an architectural decision to support it by the end of this session.
### 0c. Existing Architecture Decisions
To learn **what has already been decided and in which domain**, scan the ADR
headers — do not full-read every ADR to produce a list of numbers and domains:
```
Grep pattern="^## (Status|Summary)" glob="docs/architecture/adr-*.md" output_mode="content" -A 4
Grep pattern="\*\*Domain\*\*" glob="docs/architecture/adr-*.md" output_mode="content"
```
`## Summary` (a 2-sentence what-and-why) plus `## Status` and the Engine
Compatibility `Domain` field are exactly "what was decided and its domain". List
the ADRs found, their status, and their domains from the scan. Full-read a
specific ADR only when a new decision this session would collide with it and you
need its reasoning — not to build the inventory.
### 0d. Generate Knowledge Gap Inventory
Before proceeding, display a structured summary:
```
## Engine Knowledge Gap Inventory
Engine: [name + version]
LLM Training Covers: up to approximately [version]
Post-Cutoff Versions: [list]
### HIGH RISK Domains (must verify against engine reference before deciding)
- [Domain]: [Key changes]
### MEDIUM RISK Domains (verify key APIs)
- [Domain]: [Key changes]
### LOW RISK Domains (in training data, likely reliable)
- [Domain]: [no significant post-cutoff changes]
### Systems from GDD that touch HIGH/MEDIUM risk domains:
- [GDD system name] → [domain] → [risk level]
```
Use `AskUserQuestion`:
- Prompt: "One or more engine domains are HIGH RISK — the LLM's knowledge may be unreliable for these areas. Architectural recommendations in these domains should be cross-referenced with the engine docs before being acted on. How would you like to proceed?"
- Options:
- `[A] Proceed — flag HIGH RISK domains throughout the output`
- `[B] Let me check the engine reference first — pause here`
- `[C] Show me which domains are HIGH RISK and why`
### 0e. Existing Architecture Document
Glob `docs/architecture/architecture.md`. If it exists, this run updates it —
it never replaces it unasked. Read its `## Document Status` block and its `##`
headings, then use `AskUserQuestion`:
- Prompt: "An architecture document already exists (v[N], [last updated]). What should this run do?"
- Options: `[A] Update chosen sections in place` / `[B] Rewrite the whole document — replaces the existing file` / `[C] Stop`
On `[A]`, ask which sections. Phases 1–6 author only those and say which they
skipped; Phase 7 replaces just those sections and raises `Version` to N+1,
leaving every other section as it is. `[B]` runs the full walkthrough, and
Phase 7's ask says it replaces the existing file.
A focus-area argument (`layers`, `data-flow`, `api-boundaries`, `adr-audit`)
is `[A]` with that one section chosen: it runs only its phase (1, 3, 4 or 5),
and Phase 7 writes that section. Phase 7b still runs on the updated document —
an update is reviewed like a first draft, at the review modes that review one. With no existing document there is nothing to
update — say so, and offer the full walkthrough instead.
---
@@ -0,0 +1,39 @@
# /create-architecture — Phase 1: System Layer Mapping
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 1: System Layer Mapping
Map every system from `systems-index.md` into an architecture layer. The standard
game architecture layers are:
```
┌─────────────────────────────────────────────┐
│ PRESENTATION LAYER │ ← UI, HUD, menus, VFX, audio
├─────────────────────────────────────────────┤
│ FEATURE LAYER │ ← gameplay systems, AI, quests
├─────────────────────────────────────────────┤
│ CORE LAYER │ ← physics, input, combat, movement
├─────────────────────────────────────────────┤
│ FOUNDATION LAYER │ ← engine integration, save/load,
│ │ scene management, event bus
├─────────────────────────────────────────────┤
│ PLATFORM LAYER │ ← OS, hardware, engine API surface
└─────────────────────────────────────────────┘
```
For each GDD system, ask:
- Which layer does it belong to?
- What are its module boundaries?
- What does it own exclusively? (data, state, behaviour)
Present the proposed layer assignment and ask for approval before proceeding to
the next section. Record the approved layer map in
`production/session-state/active.md`; it goes into the document at Phase 7.
**Engine awareness check**: For each system assigned to the Core and Foundation
layers, flag if it touches a HIGH or MEDIUM risk engine domain. Show the relevant
engine reference excerpt inline.
---
@@ -0,0 +1,30 @@
# /create-architecture — Phase 2: Module Ownership Map
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 2: Module Ownership Map
For each module defined in Phase 1, define ownership:
- **Owns**: what data and state this module is solely responsible for
- **Exposes**: what other modules may read or call
- **Consumes**: what it reads from other modules
- **Engine APIs used**: which specific engine classes/nodes/signals this module
calls directly (with version and risk level noted)
Format as a table per layer, then as an ASCII dependency diagram.
**Engine awareness check**: For every engine API listed, verify against the
relevant module reference doc. If an API is post-cutoff, flag it:
```
⚠️ [ClassName.method()] — Godot 4.6 (post-cutoff, HIGH risk)
Verified against: docs/engine-reference/godot/modules/[domain].md
Behaviour confirmed: [yes / NEEDS VERIFICATION]
```
Get user approval on the ownership map, then record it in
`production/session-state/active.md`; it is written at Phase 7.
---
@@ -0,0 +1,24 @@
# /create-architecture — Phase 3: Data Flow
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 3: Data Flow
Define how data moves between modules during key game scenarios. Cover at minimum:
1. **Frame update path**: Input → Core systems → State → Rendering
2. **Event/signal path**: How systems communicate without tight coupling
3. **Save/load path**: What state is serialised, which module owns serialisation
4. **Initialisation order**: Which modules must boot before others
Use ASCII sequence diagrams where helpful. For each data flow:
- Name the data being transferred
- Identify the producer and consumer
- State whether this is synchronous call, signal/event, or shared state
- Flag any data flows that cross thread boundaries
Get user approval on each scenario, then record it in
`production/session-state/active.md`; it is written at Phase 7.
---
@@ -0,0 +1,25 @@
# /create-architecture — Phase 4: API Boundaries
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 4: API Boundaries
Define the public contracts between modules. For each boundary:
- What is the interface a module exposes to the rest of the system?
- What are the entry points (functions/signals/properties)?
- What invariants must callers respect?
- What must the module guarantee to callers?
Write in pseudocode or the project's actual language (from technical preferences).
These become the contracts programmers implement against.
**Engine awareness check**: If any interface uses engine-specific types (e.g.
`Node`, `Resource`, `Signal` in Godot), flag the version and verify the type
exists and has not changed signature in the target engine version.
Get user approval on the API boundaries, then record them in
`production/session-state/active.md`; they are written at Phase 7.
---
@@ -0,0 +1,50 @@
# /create-architecture — Phase 5: ADR Audit and Traceability Check
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 5: ADR Audit + Traceability Check
Review all existing ADRs from Phase 0c against both the architecture built in
Phases 1-4 AND the Technical Requirements Baseline from Phase 0b.
### ADR Quality Check
For each ADR:
- [ ] Does it have an Engine Compatibility section?
- [ ] Is the engine version recorded?
- [ ] Are post-cutoff APIs flagged?
- [ ] Does it have a "GDD Requirements Addressed" section?
- [ ] Does it conflict with the layer/ownership decisions made in this session?
- [ ] Is it still valid for the pinned engine version?
| ADR | Engine Compat | Version | GDD Linkage | Conflicts | Valid |
|-----|--------------|---------|-------------|-----------|-------|
| ADR-0001: [title] | ✅/❌ | ✅/❌ | ✅/❌ | None/[conflict] | ✅/⚠️ |
### Traceability Coverage Check
Map every requirement from the Technical Requirements Baseline to existing ADRs.
For each requirement, check if any ADR's "GDD Requirements Addressed" section
or decision text covers it:
| Req ID | Requirement | ADR Coverage | Status |
|--------|-------------|--------------|--------|
| TR-combat-001 | Hitbox detection per-frame | ADR-0003 | ✅ |
| TR-combat-002 | Combo state machine | — | ❌ GAP |
Count: X covered, Y gaps. For each gap, it becomes a **Required New ADR**.
### Required New ADRs
List all decisions made during this architecture session (Phases 1-4) that do
not yet have a corresponding ADR, PLUS all uncovered Technical Requirements.
Group by layer — Foundation first:
**Foundation Layer (must create before any coding):**
- `/architecture-decision [title]` → covers: TR-[id], TR-[id]
**Core Layer:**
- `/architecture-decision [title]` → covers: TR-[id]
---
@@ -0,0 +1,21 @@
# /create-architecture — Phase 6: Missing ADR List
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 6: Missing ADR List
Based on the full architecture, produce a complete list of ADRs that should exist
but don't yet. Group by priority:
**Must have before coding starts (Foundation & Core decisions):**
- [e.g. "Scene management and scene loading strategy"]
- [e.g. "Event bus vs direct signal architecture"]
**Should have before the relevant system is built:**
- [e.g. "Inventory serialisation format"]
**Can defer to implementation:**
- [e.g. "Specific shader technique for water"]
---
@@ -0,0 +1,109 @@
# /create-architecture — Phases 7 and 7b: Write and Sign-Off
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 7: Write the Master Architecture Document
**In this file:**
- Phase 7: the master architecture document template, then the write
- Phase 7b: Technical Director Sign-Off + Lead Programmer Feasibility Review: review mode check, presenting both assessments, recording the sign-off
Once all sections are approved, write the complete document to
`docs/architecture/architecture.md`.
In an update (Phase 0e `[A]`, or a focus-area argument), write only the chosen
sections instead, replacing each in place with `Edit`, and raise `Version`; the
ask below then names those sections and the version change.
Display a one-paragraph summary of what the document will contain (layers, modules, data flows, ADR gaps). Then use `AskUserQuestion`:
- "All sections approved. May I write the master architecture document?"
- [A] Yes — write to `docs/architecture/architecture.md` now
- [B] Show me the full draft inline first, then ask again
- [C] Not yet — I have more changes to discuss
The document structure:
```markdown
# [Game Name] — Master Architecture
## Document Status
- Version: [N]
- Last Updated: [date]
- Engine: [name + version]
- GDDs Covered: [list]
- ADRs Referenced: [list]
## Engine Knowledge Gap Summary
[Condensed from Phase 0d inventory — HIGH/MEDIUM risk domains and their implications]
## System Layer Map
[From Phase 1]
## Module Ownership
[From Phase 2]
## Data Flow
[From Phase 3]
## API Boundaries
[From Phase 4]
## ADR Audit
[From Phase 5]
## Required ADRs
[From Phase 6]
## Architecture Principles
[3-5 key principles that govern all technical decisions for this project,
derived from the game concept, GDDs, and technical preferences]
## Open Questions
[Decisions deferred — must be resolved before the relevant layer is built]
```
---
## Phase 7b: Technical Director Sign-Off + Lead Programmer Feasibility Review
After writing the master architecture document, perform an explicit sign-off before handoff.
**Review mode check** — apply before spawning either gate:
- `solo` → skip both. Note: "TD-ARCHITECTURE and LP-FEASIBILITY skipped — Solo mode." Go to Step 4 and record both as skipped, then Phase 8.
- `lean` → skip both (neither is a PHASE-GATE). Note: "TD-ARCHITECTURE and LP-FEASIBILITY skipped — Lean mode." Go to Step 4 and record both as skipped, then Phase 8.
- `full` → spawn both, in parallel.
**Step 1 — Spawn `technical-director` via `Agent` using gate TD-ARCHITECTURE (`.claude/docs/director-gates/td-architecture.md`):**
Pass: the architecture document path (`docs/architecture/architecture.md`), the Technical Requirements Baseline (TR-IDs and count), the ADR list with statuses, and the Engine Knowledge Gap Inventory from Phase 0d. Issue this call and Step 2's before waiting for either result.
**Step 2 — Spawn `lead-programmer` via `Agent` using gate LP-FEASIBILITY (`.claude/docs/director-gates/lp-feasibility.md`):**
Pass: architecture document path, technical requirements baseline summary, ADR list.
**Step 3 — Present both assessments to the user:**
Show the TD-ARCHITECTURE verdict (APPROVE / CONCERNS / REJECT) and the LP-FEASIBILITY verdict (FEASIBLE / CONCERNS / INFEASIBLE) side by side.
Use `AskUserQuestion` — "Technical Director and Lead Programmer have reviewed the architecture. How would you like to proceed?"
Options: `Accept — proceed to handoff` / `Revise flagged items first` / `Discuss specific concerns`.
If either verdict is REJECT or INFEASIBLE, do not offer `Accept` — the blockers are revised (or discussed) first.
`Revise flagged items first` re-drafts each flagged section and shows it for approval as in Phases 1–4; the revised document is then written once, through Phase 7's ask, and Step 4 records `REVISED after [verdict]`.
A `NOT ASSESSED` answer is never recorded as `APPROVE` or `FEASIBLE`: Step 4 records it with the input that was missing (`director-gates.md`).
**Step 4 — Record sign-off in the architecture document:**
Update the Document Status section:
```
- TD-ARCHITECTURE: [date] — APPROVE / CONCERNS (accepted) / REVISED after CONCERNS / REVISED after REJECT / NOT ASSESSED — [missing input] / skipped — [mode] mode
- LP-FEASIBILITY: [date] — FEASIBLE / CONCERNS (accepted) / REVISED after CONCERNS / REVISED after INFEASIBLE / NOT ASSESSED — [missing input] / skipped — [mode] mode
```
Show the proposed Document Status block inline, then use `AskUserQuestion`:
- "May I update the Document Status section with the sign-off results?"
- [A] Yes — apply to `docs/architecture/architecture.md`
- [B] Not yet — I want to revisit the concerns first
---
@@ -0,0 +1,65 @@
# /create-architecture — Phase 8: Handoff
> Part of `/create-architecture`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 8: Handoff
**Step 1 — Update session state**: Write a summary to `production/session-state/active.md` covering: artifact written, TD/LP sign-off verdicts, any blockers, required ADRs remaining, and next step.
**Step 2 — Output the handoff** using exactly this template (no freeform prose, no rephrasing of section titles):
---
## Architecture Complete
`docs/architecture/architecture.md` v[N] — [TD-ARCHITECTURE: APPROVE / CONCERNS (accepted) / REVISED after CONCERNS / REVISED after REJECT / NOT ASSESSED / skipped — [mode] mode]. [One sentence on what the architecture covers.]
---
## Run These ADRs Next
**1. `/architecture-decision "[Title]"` → ADR-[XXXX]**
[One sentence: what it defines and what it unblocks.]
**2. `/architecture-decision "[Title]"` → ADR-[XXXX]**
[One sentence.]
**3. `/architecture-decision "[Title]"` → ADR-[XXXX]**
[One sentence.]
**Then:** `/architecture-review`, and `/create-control-manifest` once it passes and those ADRs are Accepted — it turns them into the layer rules manifest.
List top 3 from Phase 6 in priority order. If fewer than 3 remain, list only what's outstanding.
---
## Gate-Check Readiness
> **Required before `/gate-check pre-production`:**
> - [ ] Accept ADRs: [list Proposed ADR IDs that must be Accepted]
> - [ ] Write ADRs: [list ADR IDs that must still be written]
> - [ ] Run `/architecture-review` — writes the review report and the traceability index (`docs/architecture/requirements-traceability.md`) the gate reads
> - [ ] Run `/test-setup` — scaffolds `tests/unit/`, `tests/integration/`, CI workflow, and an example test file
> - [ ] Run `/ux-design` — creates `design/ux/interaction-patterns.md` and `design/accessibility-requirements.md`
>
> Run `/gate-check pre-production` when all boxes are checked.
If nothing is blocking, write instead:
> No blockers — run `/gate-check pre-production` now.
---
## Open Questions to Watch
| ID | Summary | Priority | Resolution Path |
|----|---------|----------|-----------------|
| QQ-XX | [short description] | High / Medium / Low | [ADR or system that resolves it] |
Omit this section entirely if there are no open QQs.
---
(End of handoff. Do not add trailing commentary after the closing rule.)
---
+1 -1
View File
@@ -130,7 +130,7 @@ For `standard`/`full` (a `/create-epics` epic exists), read in full (these are s
- `production/epics/[epic-slug]/EPIC.md` — epic overview, governing ADRs, GDD requirements table
- The epic's GDD (`design/gdd/[filename].md`) — at `full` read all 8 sections; at `standard` the 5 required sections (+ conditional Formulas); at `minimal` the GDD may not exist — work from the epic brief + acceptance criteria. Always prioritise Acceptance Criteria, Formulas, and Edge Cases where present.
- `docs/architecture/control-manifest.md` — grep only this epic's layer (`Grep pattern="^## <layer> Layer Rules" path="docs/architecture/control-manifest.md" output_mode="content" -A 40`) plus the header Manifest Version date, not a full read of all layers
- `docs/architecture/tr-registry.yaml` — grep only this system's entries (`Grep pattern="system: <slug>" path="docs/architecture/tr-registry.yaml" output_mode="content" -B1 -A5`, or `id: TR-<slug>-`), not the whole cross-system registry
- `docs/architecture/tr-registry.yaml` — grep only this system's entries (`Grep pattern="system: <slug>\s*$" path="docs/architecture/tr-registry.yaml" output_mode="content" -B1 -A5`, or `id: TR-<slug>-[0-9]`; the anchors keep `combat` from matching `combat-ai`), not the whole cross-system registry
**Load each governing ADR by section — never with an unbounded full read.** A
substantial ADR exceeds the 25k-token `Read` cap, and a capped read's only
+1
View File
@@ -261,4 +261,5 @@ Use `AskUserQuestion`:
- **Rollback plan first, always** — a patch without a rollback plan is irresponsible
- **Deferred is not forgotten** — every deferred bug is listed in the record's
"Deferred to 1.1" table; run `/bug-triage` afterwards to schedule them into the 1.1 sprint
(if the project has no sprint plan, as on the default minimal workflow, into the brief's build order)
- **Player communication is part of the patch** — `/patch-notes` is a required output, not optional
+2
View File
@@ -15,6 +15,8 @@ the pre-1.1 name for the same flag: treat `--depth <mode>` exactly as
wins and `--depth` is ignored — say so. No block → defaults in
`.claude/docs/config-resolution.md`.
# Design Review
## Phase 0: Parse Arguments
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,124 @@
# /design-system — Phase 1: Parse Arguments & Validate
> Part of `/design-system`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 1. Parse Arguments & Validate
**In this file:**
- `docs.density`
- No system name given: the systems index picks the next one
- Detect retrofit mode
- `workflow` for this system, and `## Summary` at every tier
See `.claude/docs/director-gates.md` for the full check pattern. Individual gate definitions live in `.claude/docs/director-gates/[gate-id].md` — the spawned agent reads its own gate file; do not read it in the parent session.
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).
**`docs.density`** — it controls per-section *depth*, where `workflow`
controls which sections exist. `modes.rigor` sets both together; set
`docs.density` explicitly to vary depth alone: `terse` (the default, via `rigor: minimal`) = bullet points, 2–5 lines per section,
skip rationale and preambles; `balanced` = paragraphs with light rationale
(`rigor: standard`); `thorough` = full prose with rationale, examples, and alternatives
considered. Apply it to every section you author. Mandated structures (the
Formulas variable table, Given-When-Then acceptance criteria) are correctness
requirements at every density — `terse` trims the surrounding prose, never the
required structure itself.
A system name or retrofit path is **required**. If missing:
1. Check if `design/gdd/systems-index.md` exists.
2. If it exists: read it, find the highest-priority system with status "Not Started" or equivalent, and use `AskUserQuestion`:
- Prompt: "The next system in your design order is **[system-name]** ([priority] | [layer]). Start designing it?"
- Options: `[A] Yes — design [system-name]` / `[B] Pick a different system` / `[C] Stop here`
- If [A]: proceed with that system name. If [B]: ask which system to design (plain text). If [C]: exit.
3. If no systems index exists, fail with:
> "Usage: `/design-system <system-name>` — e.g., `/design-system movement`
> Or to fill gaps in an existing GDD: `/design-system retrofit design/gdd/[system-name].md`
> No systems index found. Run `/map-systems` first to map your systems and get the design order."
**Detect retrofit mode:**
If the argument starts with `retrofit` or the argument is a file path to an
existing `.md` file in `design/gdd/`, enter **retrofit mode**:
1. Read the existing GDD file.
2. Identify which of the 8 **possible** sections are present (scan for section
headings): Overview, Player Fantasy, Detailed Design/Rules, Formulas,
Edge Cases, Dependencies, Tuning Knobs, Acceptance Criteria.
**Which of them are *required* depends on the effective tier** (§1) — at
`standard` only 5 are, plus Formulas for math categories, and Player Fantasy
and Tuning Knobs are skipped **by design**. Report an absent section as a gap
only when the tier requires it; otherwise list it as available-to-add. Calling
all 8 required here reports two by-design-absent sections as gaps on every
`standard` project.
3. Identify which sections contain only placeholder text (`[To be designed]` or
equivalent — blank, a single line, or obviously incomplete).
4. Present to the user before doing anything:
```
## Retrofit: [System Name]
File: design/gdd/[filename].md
Sections already written (will not be touched):
✓ [section name]
✓ [section name]
Missing or incomplete sections (will be authored):
✗ [section name] — missing
✗ [section name] — placeholder only
```
5. Ask: "Shall I fill the [N] missing sections? I will not modify any existing content."
6. If yes: proceed to **Phase 2 (Gather Context)** as normal, but in **Phase 3**
skip creating the skeleton (file already exists) and in **Phase 4** skip
sections that are already complete. Only run the section cycle for missing/
incomplete sections.
7. **Never overwrite existing section content.** Use Edit tool to replace only
`[To be designed]` placeholders or empty section bodies.
If NOT in retrofit mode, normalize the system name to kebab-case for the
filename (e.g., "combat system" becomes `combat-system`).
**`workflow`** for this system (per `.claude/docs/workflow-modes.md`) — use the
`system_overrides` row for this system if the block lists one, else the project
value.
The resolved tier determines which GDD sections are **required** (applied in §4).
**`## Summary` is required at every tier and is not one of the 8** — §5-pre
authors it unconditionally (*"This runs at every tier"*), but it appeared in none
of the per-tier lists below, and these lists are what other skills and gates
apply. A GDD checked against a tier list alone would pass with no Summary, the
one section `/review-all-gdds` and the tiered-loading readers depend on. Read
every list below as "`## Summary`, plus:".
- `full` — all 8 sections
- `standard` — Overview, Detailed Design, Edge Cases, Dependencies, Acceptance
Criteria (5 required); **Formulas conditional** — required when the system
**defines numeric rules**: rates, curves, thresholds, costs, damage, drop
weights, or any value a balance pass would tune. Optional only when the system
defines no such value. **The `Category` in `systems-index.md` is a hint, not
the test** — `Gameplay`, `Economy` and `Progression` systems almost always
qualify, and a `Core`, `UI` or `Persistence` system that defines a numeric rule
qualifies too. If the Detailed Design states a quantity that is not a constant
of the engine, Formulas is required. **Player Fantasy and Tuning Knobs skipped**
unless `workflow_overrides` force them (`tuning_knobs: true` forces Tuning Knobs)
> **Do not gate this on a category token.** A rule of the form "required when
> the system category is combat / economy / progression / AI" does not work:
> those four tokens are not what `/map-systems` writes — `templates/systems-index.md`
> defines the categories as `Core · Gameplay · Progression · Economy ·
> Persistence · UI · Audio · Narrative · Meta` and lists **combat and AI as
> example systems under `Gameplay`**. A combat system categorised exactly as the
> template instructs matches none of the four, and Formulas would be dropped for
> the system most likely to need it.
- `minimal` — a GDD is not required (the game brief replaces it). If invoked
voluntarily at minimal, author exactly the 5 standard sections (Overview,
Detailed Design, Edge Cases, Dependencies, Acceptance Criteria) — the
conditional Formulas rule does NOT re-apply at minimal — and tell the user
the GDD is optional at this workflow level.
Retrofit mode is unaffected — it fills whatever sections are missing regardless
of tier.
---
@@ -0,0 +1,244 @@
# /design-system — Phase 2: Gather Context
> Part of `/design-system`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 2. Gather Context (Read Phase)
**In this file:**
- 2a: Required Reads
- 2b: Dependency Reads
- 2c: Optional Reads
- 2d: Present Context Summary
- 2e: Technical Feasibility Pre-Check
Read all relevant context **before** asking the user anything. This is the skill's
primary advantage over ad-hoc design — it arrives informed.
### 2a: Required Reads
> **At `minimal`** (design-system is voluntary at this tier): read
> `design/game-brief.md` in place of the game concept, and **skip the systems-index
> read** — neither `game-concept.md` nor `systems-index.md` exists at `minimal`.
> Author from the brief's relevant MVP feature and its core loop.
>
> **This callout keys on the PROJECT tier, not this system's effective tier.**
> The two differ whenever `workflow_overrides.system_overrides` bumps one system
> above a `minimal` project — the configuration `.claude/docs/settings-guidance.md`
> advertises as the reason the override exists ("bump one deep system"). Those two
> files are absent because the *project* is `minimal`; raising *this system* to
> `standard` or `full` does not create them. So on a `minimal` project, take this
> branch **even for an overridden system**, and read the brief.
>
> The effective tier still governs everything downstream — the required section
> set (§1), the skeleton (§3), the section cycle (§4) and §5a. Only the
> required-*reads* branch here follows the project tier.
>
> **Then derive `Category`, `Layer` and `Priority` from the brief, once, here.**
> Six later steps are keyed on the systems index you just skipped — §2e's engine
> domain, Section A's and Section B's recommended options, the Visual/Audio
> REQUIRED table, §6 specialist routing, and §5-pre's Quick reference — and none
> of them has an absent-index branch. An overridden system reaches all six at
> `standard` or `full`, so "skip the index" leaves them with no input at all.
> Derive from the brief instead:
>
> - **`Category`** — one of the nine in `templates/systems-index.md`
> (`Core · Gameplay · Progression · Economy · Persistence · UI · Audio ·
> Narrative · Meta`), chosen from what the brief says the system *does*.
> - **`Layer`** — `Foundation` if other systems depend on it, else `Feature`.
> - **`Priority`** — `MVP` if the brief's build order lists it, else `Post-MVP`.
>
> Carry all three for the rest of the run and treat them as the index's answer.
> **Mark them inferred** in §5-pre's Quick reference (*"Category: Gameplay
> (inferred from the brief — no systems index at this tier)"*) so a later reader
> does not mistake a derivation for an indexed fact. Do **not** write a systems
> index to hold them: `/map-systems` owns that file (§5d).
>
> Read literally without this rule, an overridden system resolves to `full`, falls
> through to the fail-fast reads below, and aborts with *"No game concept found.
> Run `/brainstorm` first"* — killing the escape hatch on step one of the very
> configuration it was built for.
- **Game concept**: Read `design/gdd/game-concept.md` — fail if missing:
> "No game concept found. Run `/brainstorm` first."
- **Systems index**: Read `design/gdd/systems-index.md` — fail if missing:
> "No systems index found. Run `/map-systems` first to map your systems."
- **Target system**: Find the system in the index. If not listed, warn:
> "[system-name] is not in the systems index. Would you like to add it, or
> design it as an off-index system?"
- **Entity registry**: If `design/registry/entities.yaml` exists, grep it for
the entries this system owns and the entries that reference it:
```
Grep pattern="source: design/gdd/[system-name].md" path="design/registry/entities.yaml" output_mode="content" -A 6
Grep pattern="design/gdd/[system-name].md" path="design/registry/entities.yaml" output_mode="content" -B 8
```
`referenced_by:` is a block list (the key and its paths are on separate
lines), so match the path with `-B 8` context to see the owning entry; a
`referenced_by.*[system-name]` one-liner never matches it. Hold these
in context as **known facts** — values that other GDDs have already
established and this GDD must not contradict.
- **Reflexion log**: Read `docs/consistency-failures.md` if it exists.
Extract entries whose Domain matches this system's category. These are
recurring conflict patterns — present them under "Past failure patterns"
in the Phase 2d context summary so the user knows where mistakes have
occurred before in this domain.
### 2b: Dependency Reads
From the systems index, identify:
- **Upstream dependencies**: Systems this one depends on (decisions this system
must respect).
- **Downstream dependents**: Systems that depend on this one (expectations this
system must satisfy).
For each dependency GDD that exists, read **only the four sections that carry the
cross-system contract** — not the whole GDD:
```
Grep pattern="^## ([0-9]+\. )?(Dependencies|Formulas|Edge Cases|Tuning Knobs)" glob="design/gdd/[dep].md" output_mode="content" -A 20
```
- Key interfaces and data flow (from Dependencies)
- Formulas that reference this system's outputs
- Edge cases that assume this system's behavior
- Tuning knobs that feed into this system
Much of this is already in `entities.yaml` (loaded in 2a) — the registry's
`formula_map`/`constant_map` carry the owned values with their `source:`. Use the
registry first; the section grep fills what it does not hold.
### 2c: Optional Reads
- **Game pillars**: Read `design/gdd/game-pillars.md` if it exists
- **Existing GDD**: Read `design/gdd/[system-name].md` if it exists (resume, don't
restart from scratch)
- **Related systems**: do **not** glob-and-read `design/gdd/*.md` hunting for
"thematically related" systems — there is no deterministic proxy for that and it
is the read the registry exists to replace. `entities.yaml` (2a) already holds
the cross-system facts a related GDD would supply. If a specific overlap is
known, treat it as a dependency above and section-grep it; otherwise rely on the
registry.
### 2d: Present Context Summary
Before starting design work, present a brief summary to the user:
> **Designing: [System Name]**
> - Priority: [from index] | Layer: [from index]
> - Depends on: [list, noting which have GDDs vs. undesigned]
> - Depended on by: [list, noting which have GDDs vs. undesigned]
> - Existing decisions to respect: [key constraints from dependency GDDs]
> - Pillar alignment: [which pillar(s) this system primarily serves]
> - **Known cross-system facts (from registry):**
> - [entity_name]: [attribute]=[value], [attribute]=[value] (owned by [source GDD])
> - [item_name]: [attribute]=[value], [attribute]=[value] (owned by [source GDD])
> - [formula_name]: variables=[list], output=[min–max] (owned by [source GDD])
> - [constant_name]: [value] [unit] (owned by [source GDD])
> *(These values are locked — if this GDD needs different values, surface
> the conflict before writing. Do not silently use different numbers.)*
>
> If no registry entries are relevant: omit the "Known cross-system facts" section.
If any upstream dependencies are undesigned, warn:
> "[dependency] doesn't have a GDD yet. We'll need to make assumptions about
> its interface. Consider designing it first, or we can define the expected
> contract and flag it as provisional."
### 2e: Technical Feasibility Pre-Check
Before asking the user to begin designing, load engine context and surface any
constraints or knowledge gaps that will shape the design.
**Step 1 — Determine the engine domain for this system:**
Map the system's category (from systems-index.md) to an engine domain:
Keyed on the `Category` column of `systems-index.md`. All nine categories
`templates/systems-index.md` defines appear here; where a category spans several
engine domains, pick the row matching what the system actually does and say
which you picked.
| `Category` | Engine Domain |
|-----------|--------------|
| `Gameplay` | **Physics** for combat / collision / movement; **Navigation** for AI and pathfinding; **Scripting** for rule-only systems with no engine surface |
| `Core` | **Core** — scene management, state, resource loading; **Input** for controls and keybinding |
| `UI` | UI |
| `Audio` | Audio |
| `Narrative` | Scripting — dialogue, quests, cutscenes |
| `Progression` | Scripting — save-adjacent rule logic, no dedicated domain |
| `Economy` | Scripting — data and rule logic, no dedicated domain |
| `Persistence` | Core — save/load, settings, serialization |
| `Meta` | Core — analytics, tutorials, accessibility plumbing |
> Animation, Rendering and Networking are engine domains with no category of
> their own: a system needing them will be `Gameplay` or `Core`. Name the domain
> you read the reference for, whichever row you came in on.
**Step 2 — Read engine context (if available):**
- Identify the engine and version: read `engine.name` and `engine.version` from `project.yaml`. Resolve each field independently — if its key is absent or empty (including when `project.yaml` has no `engine:` block), fall back to `.claude/docs/technical-preferences.md` (a `[TO BE CONFIGURED]` value means not set)
- If engine is configured, read `docs/engine-reference/[engine]/VERSION.md`
- Read `docs/engine-reference/[engine]/modules/[domain].md` if it exists.
**If it does not exist, say so by name** — *"no engine reference for `[domain]`
under `docs/engine-reference/[engine]/modules/`; feasibility not checked against
the pinned engine"* — and carry that into §5-pre. A silent skip here is
indistinguishable from a feasibility check that ran and found nothing wrong,
which is the failure `.claude/rules/skill-authoring.md` obligation 3 exists to
stop.
> **This is not a rare branch.** The domain table above names `Scripting` and
> `Core` for five of the nine categories (`Narrative`, `Progression`, `Economy`
> → Scripting; `Persistence`, `Meta` → Core), plus a sub-row each under
> `Gameplay` and `Core`. The Godot reference ships `animation, audio, input,
> navigation, networking, physics, rendering, ui` — **there is no
> `scripting.md` and no `core.md`**. So the majority of non-`Gameplay` systems
> hit the absent branch every time, and `if it exists` turned that into
> silence. Either the reference gains those two files or the check reports it;
> until the former, do the latter.
- Read `docs/engine-reference/[engine]/breaking-changes.md` for domain-relevant entries
- Find the domain-matching ADRs without reading every ADR to learn the field you
filter on — grep the Domain field first, then read only the matches:
```
Grep pattern="\*\*Domain\*\*" glob="docs/architecture/adr-*.md" output_mode="content"
```
Read only the ADRs whose Domain matches this system's category (its `## Decision`
and `## Engine Compatibility` sections); skip the rest.
**Step 3 — Present the Feasibility Brief:**
If engine reference docs exist, present before starting design:
```
## Technical Feasibility Brief: [System Name]
Engine: [name + version]
Domain: [domain]
### Known Engine Capabilities (verified for [version])
- [capability relevant to this system]
- [capability 2]
### Engine Constraints That Will Shape This Design
- [constraint from engine-reference or existing ADR]
### Knowledge Gaps (verify before committing to these)
- [post-cutoff feature this design might rely on — mark HIGH/MEDIUM risk]
### Existing ADRs That Constrain This System
- ADR-XXXX: [decision summary] — means [implication for this GDD]
(or "None yet")
```
If no engine reference docs exist (engine not yet configured), show a short note:
> "No engine configured yet — skipping technical feasibility check. Run
> `/setup-engine` before moving to architecture if you haven't already."
**Step 4 — Ask before proceeding:**
Use `AskUserQuestion`:
- "Any constraints to add before we begin, or shall we proceed with these noted?"
- Options: "Proceed with these noted", "Add a constraint first", "I need to check the engine docs — pause here"
---
Use `AskUserQuestion`:
- "Ready to start designing [system-name]?"
- Options: "Yes, let's go", "Show me more context first", "Design a dependency first"
---
@@ -0,0 +1,134 @@
# /design-system — Phase 3: Create File Skeleton
> Part of `/design-system`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 3. Create File Skeleton
**In this file:**
- Which sections to scaffold at the resolved tier
- The GDD skeleton
- Writing the file, then the session state update
Once the user confirms, **immediately** create the GDD file with empty section
headers. This ensures incremental writes have a target.
**Scaffold only the sections required at the resolved tier** (§1): at
`standard`, omit Player Fantasy and Tuning Knobs (and Formulas only when the
system defines no numeric rule — see §1; the category is a hint, not the test);
at `full`, scaffold all 8.
**Only the sections §1 named as omitted are skipped** — do not leave empty
`[To be designed]` placeholders for those. Every other section in the template
is scaffolded with its placeholder, including the ones §4 has not decided yet.
This sentence governs the three tier omissions above (Player Fantasy, Tuning
Knobs, and Formulas when no numeric rule exists) and nothing else: it is not a
licence to strip a section because it looks optional, and §4 cannot fill a
section §3 never created.
Use the template structure from `.claude/docs/templates/game-design-document.md`:
```markdown
# [System Name]
> **Status**: In Design
> **Author**: [user + agents]
> **Last Updated**: [today's date]
> **Last Verified**: [today's date]
> **Implements Pillar**: [from context]
## Summary
[To be designed]
> **Quick reference** — Layer: `[Foundation | Core | Feature | Presentation]` · Priority: `[MVP | Vertical Slice | Alpha | Full Vision]` · Key deps: `[System names or "None"]`
## Overview
[To be designed]
## Player Fantasy
[To be designed]
## Detailed Design
### Core Rules
[To be designed]
### States and Transitions
[To be designed]
### Interactions with Other Systems
[To be designed]
## Formulas
[To be designed]
## Edge Cases
[To be designed]
## Dependencies
[To be designed]
## Tuning Knobs
[To be designed]
## Visual/Audio Requirements
[To be designed]
## Game Feel
[To be designed]
## UI Requirements
[To be designed]
## Cross-References
[To be designed]
## Acceptance Criteria
[To be designed]
## Open Questions
[To be designed]
```
> **This skeleton and the template must stay identical in section set and
> order.** They diverged once and it was invisible: the skeleton omitted
> `## Game Feel` and `## Cross-References`, so §3's own rule — *"§4 cannot fill a
> section §3 never created"* — made both unreachable **at every tier, `full`
> included**, while §3's prose above still said *"every other section in the
> template is scaffolded"*. Two agents authoring a combat GDD noticed the gap
> only by opening the template. If you add a section to one file, add it to the
> other in the same commit.
Ask: "May I create the skeleton file at `design/gdd/[system-name].md`?"
If the user declines: Stop with the following message:
> "Verdict: **BLOCKED** — skeleton creation declined. The design session cannot proceed without the skeleton file, as all subsequent phases use it as the base. Re-run `/design-system [system]` when ready to create the file."
Do not proceed to Section A.
After writing, update `production/session-state/active.md`:
- Use Glob to check if the file exists.
- If it **does not exist**: use the **Write** tool to create it. Never attempt Edit on a file that may not exist.
- If it **already exists**: use the **Edit** tool to update the relevant fields.
File content:
- Task: Designing [system-name] GDD
- Current section: Starting (skeleton created)
- File: design/gdd/[system-name].md
---
@@ -0,0 +1,527 @@
# /design-system — Phase 4: Section-by-Section Design
> Part of `/design-system`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 4. Section-by-Section Design
**In this file:**
- The Section Cycle
- Section-Specific Guidance
- Section A: Overview
- Section B: Player Fantasy
- Section C: Detailed Design (Core Rules, States, Interactions)
- Section D: Formulas
- Section E: Edge Cases
- Section F: Dependencies
- Section G: Tuning Knobs
- Section H: Acceptance Criteria
- Optional Sections: Visual/Audio, Game Feel, UI Requirements, Cross-References, Open Questions
**Author only the sections required at the resolved tier** (§1). At `standard`,
the walk covers A (Overview), C (Detailed Design), E (Edge Cases),
F (Dependencies), H (Acceptance Criteria) — plus D (Formulas) when the system
defines numeric rules (see §1; the category is a hint, not the test); skip B (Player Fantasy) and
G (Tuning Knobs) unless `workflow_overrides.tuning_knobs: true` forces G. At
`full`, walk all eight (A–H). At `minimal`, the GDD is optional — if authoring
voluntarily, walk the standard set. Any `system_overrides.<system>` tier was
already folded into the resolved tier in §1.
Walk through each required section in order. For **each section**, follow this cycle:
### The Section Cycle
```
Context -> Questions -> Options -> Decision -> Draft -> Approval -> Write
```
1. **Context**: State what this section needs to contain, and surface any relevant
decisions from dependency GDDs that constrain it.
2. **Questions**: Ask clarifying questions specific to this section. Use
`AskUserQuestion` for constrained questions, conversational text for open-ended
exploration.
3. **Options**: Where the section involves design choices (not just documentation),
present 2-4 approaches with pros/cons. Explain reasoning in conversation text,
then use `AskUserQuestion` to capture the decision.
4. **Decision**: User picks an approach or provides custom direction.
5. **Draft**: Write the section content in conversation text for review. Flag any
provisional assumptions about undesigned dependencies.
6. **Approval**: Per the resolved `modes.automation` mode
(`.claude/docs/automation-modes.md`):
**In `collaborative` mode**: Immediately after the draft — in the SAME
response — use `AskUserQuestion`. **NEVER use plain text. NEVER skip
this step.**
- Prompt: "Approve the [Section Name] section?"
- Options: `[A] Approve — write it to file` / `[B] Make changes — describe what to fix` / `[C] Start over`
**The draft and the approval widget MUST appear together in one response.
If the draft appears without the widget, the user is left at a blank prompt
with no path forward — this is a protocol violation in collaborative mode.**
**In `guided` mode**: Write the section immediately after the draft with
a brief one-line summary of what was decided. Skip the per-section widget;
the multi-section authoring rule (no per-section confirmation) applies.
**In `autonomous` mode**: Write the section directly and call
`log_decision` with `Decision point: Approve [Section Name] section`,
`Chosen: [A] Approve`, `Category: minor`.
7. **Write**: Use the Edit tool to replace the placeholder with the approved content.
**CRITICAL**: Always include the section heading in the `old_string` to ensure
uniqueness — never match `[To be designed]` alone, as multiple sections use the
same placeholder and the Edit tool requires a unique match. Use this pattern:
```
old_string: "## [Section Name]\n\n[To be designed]"
new_string: "## [Section Name]\n\n[approved content]"
```
Confirm the write.
8. **Registry conflict check** (Sections C and D only — Detailed Design and Formulas):
After writing, scan the section content for entity names, item names, formula
names, and numeric constants that appear in the registry. For each match:
- Compare the value just written against the registry entry.
- If they differ: **surface the conflict immediately** before starting the next
section. Do not continue silently.
> "Registry conflict: [name] is registered in [source GDD] as [registry_value].
> This section just wrote [new_value]. Which is correct?"
- If new (not in registry): flag it as a candidate for registry registration
(will be handled in Phase 5).
After writing each section, update `production/session-state/active.md` with the
completed section name. Use Glob to check if the file exists — use Write to create
it if absent, Edit to update it if present.
### Section-Specific Guidance
Each section has unique design considerations and may benefit from specialist agents:
**Every skipped spawn is announced.** When a section's review-mode check below
skips its specialist — in `lean` as well as `solo` — print that section's note
with the mode it ran in, e.g. "`creative-director` not consulted — Lean mode.
Review manually before production." A section drafted without its specialist
must say so in the output, whichever mode skipped it.
---
### Section A: Overview
**Goal**: One paragraph a stranger could read and understand.
**Derive recommended options before building the widget**: Read the system's category and layer from the systems index (already in context from Phase 2), then determine the recommended option for each tab:
- **Framing tab**: keyed on the `Category` column (`Core · Gameplay · Progression · Economy · Persistence · UI · Audio · Narrative · Meta`). Player-facing — `Gameplay`, `UI`, `Audio`, `Narrative` → `[C] Both` recommended. Internal — `Core`, `Persistence`, `Meta` → `[A]` recommended. Mixed — `Economy`, `Progression` → `[C] Both`. **Tiebreak, when Layer and Category disagree** (a `Foundation`-layer `Gameplay` system is the common case): **Category wins** — the framing describes what the section is *about*, and a player-facing system stays player-facing wherever it sits in the dependency graph.
- **ADR ref tab**: Glob `docs/architecture/adr-*.md` and grep for the system name in the GDD Requirements section of any ADR. If a matching ADR is found → `[A] Yes — cite the ADR` recommended. If none found → `[B] No` recommended.
- **Fantasy tab**: Foundation/Infrastructure layer → `[B] No` recommended. All other categories → `[A] Yes` recommended.
Append `(Recommended)` to the appropriate option text in each tab.
**Framing questions (ask BEFORE drafting)**: Use `AskUserQuestion` with a multi-tab widget:
- Tab "Framing" — "How should the overview frame this system?" Options: `[A] As a data/infrastructure layer (technical framing)` / `[B] Through its player-facing effect (design framing)` / `[C] Both — describe the data layer and its player impact`
- Tab "ADR ref" — "Should the overview reference the existing ADR for this system?" Options: `[A] Yes — cite the ADR for implementation details` / `[B] No — keep the GDD at pure design level`
- Tab "Fantasy" — "Does this system have a player fantasy worth stating?" Options: `[A] Yes — players feel it directly` / `[B] No — pure infrastructure, players feel what it enables`
Use the answers to shape the draft. **In `collaborative` mode, do NOT answer
these questions yourself and auto-draft** — the widget must appear. In `guided`
and `autonomous`, this is a MINOR framing decision: select the recommended
option derived above, state it in one line, and proceed (that is the whole
point of pre-deriving recommendations). Applies to every "ask BEFORE drafting"
widget in this section walk, not just this one.
**Questions to ask**:
- What is this system in one sentence?
- How does a player interact with it? (active/passive/automatic)
- Why does this system exist — what would the game lose without it?
**Cross-reference**: Check that the description aligns with how the systems index
describes it. Flag discrepancies.
**Design vs. implementation boundary**: Overview questions must stay at the behavior
level — what the system *does*, not *how it is built*. If implementation questions
arise during the Overview (e.g., "Should this use an Autoload singleton or a signal
bus?"), note them as "→ becomes an ADR" and move on. Implementation patterns belong
in `/architecture-decision`, not the GDD. The GDD describes behavior; the ADR
describes the technical approach used to achieve it.
---
### Section B: Player Fantasy
**Goal**: The emotional target — what the player should *feel*.
**Derive recommended option before building the widget**: Read the system's category and layer from Phase 2 context:
Keyed on the `Category` column (`Core · Gameplay · Progression · Economy · Persistence · UI · Audio · Narrative · Meta`):
- Player-facing — `Gameplay`, `UI`, `Audio`, `Narrative` → `[A] Direct` recommended
- Internal — `Core`, `Persistence`, `Meta` → `[B] Indirect` recommended
- Mixed — `Economy`, `Progression` → `[C] Both` recommended
**When Layer and Category disagree, Category wins** — same tiebreak as the
Framing tab above.
Append `(Recommended)` to the appropriate option text.
**Framing question (ask BEFORE drafting)**: Use `AskUserQuestion`:
- Prompt: "Is this system something the player engages with directly, or infrastructure they experience indirectly?"
- Options: `[A] Direct — player actively uses or feels this system` / `[B] Indirect — player experiences the effects, not the system` / `[C] Both — has a direct interaction layer and infrastructure beneath it`
Use the answer to frame the Player Fantasy section appropriately. Do NOT assume the answer.
**Questions to ask**:
- What emotion or power fantasy does this serve?
- What reference games nail this feeling? What specifically creates it?
- Is this a "system you love engaging with" or "infrastructure you don't notice"?
**Cross-reference**: Must align with the game pillars. If the system serves a pillar,
quote the relevant pillar text.
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Draft the section without the specialist. Add a note: "`creative-director` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless this is a section with HIGH implementation risk (Sections D and H only). For other sections, draft without the agent.
- `full` → spawn as described below.
**Agent delegation (MANDATORY)**: After the framing answer is given but before drafting,
spawn `creative-director` via `Agent`:
- Provide: system name, framing answer (direct/indirect/both), game pillars, any reference games the user mentioned, the game concept summary
- Ask: "Shape the Player Fantasy for this system. What emotion or power fantasy should it serve? What player moment should we anchor to? What tone and language fits the game's established feeling? Be specific — give me 2-3 candidate framings."
- Collect the creative-director's framings and present them to the user alongside the draft.
**Do NOT draft Section B without first consulting `creative-director`.** The framing
answer tells us *what kind* of fantasy it is; the creative-director shapes *how it's
described* — tone, language, the specific player moment to anchor to.
---
### Section C: Detailed Design (Core Rules, States, Interactions)
**Goal**: Unambiguous specification a programmer could implement without questions.
This is usually the largest section. Break it into sub-sections:
1. **Core Rules**: The fundamental mechanics. Use numbered rules for sequential
processes, bullets for properties.
2. **States and Transitions**: If the system has states, map every state and
every valid transition. Use a table.
3. **Interactions with Other Systems**: For each dependency (upstream and downstream),
specify what data flows in, what flows out, and who owns the interface.
**Questions to ask**:
- Walk me through a typical use of this system, step by step
- What are the decision points the player faces?
- What can the player NOT do? (Constraints are as important as capabilities)
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Draft the section without the specialist. Add a note naming them: "`[the Section 6 routing table's Primary and Supporting Agents for this category]` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless this is a section with HIGH implementation risk (Sections D and H only). For other sections, draft without the agent.
- `full` → spawn as described below.
**Agent delegation (MANDATORY)**: Before drafting Section C, spawn specialist agents via `Agent` in parallel:
- Look up the system category in the routing table (Section 6 of this skill)
- Spawn the Primary Agent AND Supporting Agent(s) listed for this category
- Provide each agent: system name, game concept summary, pillar set, dependency GDD excerpts, the specific section being worked on
- Collect their findings before drafting
- Surface any disagreements between agents to the user via `AskUserQuestion`
- Draft only after receiving specialist input
**Do NOT draft Section C without first consulting the appropriate specialists.** A `systems-designer` reviewing rules and mechanics will catch design gaps the main session cannot.
**Cross-reference**: For each interaction listed, verify it matches what the
dependency GDD specifies. If a dependency defines a value or formula and this
system expects something different, flag the conflict.
---
### Section D: Formulas
**Goal**: Every mathematical formula, with variables defined, ranges specified,
and edge cases noted.
**Completion Steering — always begin each formula with this exact structure:**
```
The [formula_name] formula is defined as:
`[formula_name] = [expression]`
**Variables:**
| Variable | Type | Range | Source | Description |
|----------|------|-------|--------|-------------|
| [name] | float/int | [min–max] | data file / calculated / constant | [what it represents] |
**Output Range:** [min] to [max] under normal play; [behaviour at extremes]
**Example:** [worked example with real numbers]
```
Do NOT write `[Formula TBD]` or describe a formula in prose without the variable
table. A formula without defined variables cannot be implemented without guesswork.
> **These columns must match `templates/game-design-document.md` exactly.** They
> did not: this block said `Symbol` where the template says `Source`, so a
> correctly-authored GDD was wrong against whichever of the two its reader
> happened to hold. `Source` is the column that stays, because it is what carries
> the coding-standards rule *"gameplay values must be data-driven (external
> config), never hardcoded"* into the design document — a variable marked
> `data file` is a tuning knob, one marked `constant` is a deliberate exception,
> and the distinction is invisible under a `Symbol` column. Put a symbol, where
> one helps, in the expression itself.
**Questions to ask**:
- What are the core calculations this system performs?
- Should scaling be linear, logarithmic, or stepped?
- What should the output ranges be at early/mid/late game?
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Draft the section without the specialist. Add a note: "`systems-designer` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless this is a section with HIGH implementation risk (Sections D and H only). For other sections, draft without the agent.
- `full` → spawn as described below.
**Agent delegation (MANDATORY)**: Before proposing any formulas or balance values, spawn specialist agents via `Agent` in parallel:
- **Always spawn `systems-designer`**: provide Core Rules from Section C, tuning goals from user, balance context from dependency GDDs. Ask them to propose formulas with variable tables and output ranges.
- **For economy/cost systems, also spawn `economy-designer`**: provide placement costs, upgrade cost intent, and progression goals. Ask them to validate cost curves and ratios.
- Present the specialists' proposals to the user for review via `AskUserQuestion`
- The user decides; the main session writes to file
- **Do NOT invent formula values or balance numbers without specialist input.** A user without balance design expertise cannot evaluate raw numbers — they need the specialists' reasoning.
**Cross-reference**: If a dependency GDD defines a formula whose output feeds into
this system, reference it explicitly. Don't reinvent — connect.
---
### Section E: Edge Cases
**Goal**: Explicitly handle unusual situations so they don't become bugs.
**Completion Steering — format each edge case as:**
- **If [condition]**: [exact outcome]. [rationale if non-obvious]
Example (adapt terminology to the game's domain):
- **If [resource] reaches 0 while [protective condition] is active**: hold at minimum until condition ends, then apply consequence.
- **If two [triggers/events] fire simultaneously**: resolve in [defined priority order]; ties use [defined tiebreak rule].
Do NOT write vague entries like "handle appropriately" — each must name the exact
condition and the exact resolution. An edge case without a resolution is an open
design question, not a specification.
**Questions to ask**:
- What happens at zero? At maximum? At out-of-range values?
- What happens when two rules apply at the same time?
- What happens if a player finds an unintended interaction? (Identify degenerate strategies)
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Draft the section without the specialist. Add a note: "`systems-designer` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless this is a section with HIGH implementation risk (Sections D and H only). For other sections, draft without the agent.
- `full` → spawn as described below.
**Agent delegation (MANDATORY)**: Spawn `systems-designer` via `Agent` before finalising edge cases. Provide: the completed Sections C and D, and ask them to identify edge cases from the formula and rule space that the main session may have missed. For narrative systems, also spawn `narrative-director`. Present their findings and ask the user which to include.
**Cross-reference**: Check edge cases against dependency GDDs. If a dependency
defines a floor, cap, or resolution rule that this system could violate, flag it.
---
### Section F: Dependencies
**Goal**: Map every system connection with direction and nature.
This section is partially pre-filled from the context gathering phase. Present the
known dependencies from the systems index and ask:
- Are there dependencies I'm missing?
- For each dependency, what's the specific data interface?
- Which dependencies are hard (system cannot function without it) vs. soft
(enhanced by it but works without it)?
**Cross-reference**: This section must be bidirectionally consistent. If this system
lists "depends on Combat", then the Combat GDD should list "depended on by [this
system]". Flag any one-directional dependencies for correction.
---
### Section G: Tuning Knobs
**Goal**: Every designer-adjustable value, with safe ranges and extreme behaviors.
**Questions to ask**:
- What values should designers be able to tweak without code changes?
- For each knob, what breaks if it's set too high? Too low?
- Which knobs interact with each other? (Changing A makes B irrelevant)
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Derive the knobs from Section D's variable table yourself. Add a note: "`systems-designer` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless Section D defines a formula whose knobs interact (changing one makes another inert).
- `full` → delegate as described below.
**Agent delegation**: If formulas are complex, delegate to `systems-designer`
to derive tuning knobs from the formula variables.
> The guard above was missing here while Sections B, C, D, E and H all carried
> one — and this delegation names `systems-designer`, the same agent Section D's
> guard has already told a `solo` run to skip. Read without it, `solo` skips the
> specialist for the formulas and then consults it for the knobs derived from
> those same formulas.
**Cross-reference**: If a dependency GDD lists tuning knobs that affect this system,
reference them here. Don't create duplicate knobs — point to the source of truth.
---
### Section H: Acceptance Criteria
**Goal**: Testable conditions that prove the system works as designed.
**Completion Steering — format each criterion as Given-When-Then:**
- **GIVEN** [initial state], **WHEN** [action or trigger], **THEN** [measurable outcome]
Example (adapt terminology to the game's domain):
- **GIVEN** [initial state], **WHEN** [player action or system trigger], **THEN** [specific measurable outcome].
- **GIVEN** [a constraint is active], **WHEN** [player attempts an action], **THEN** [feedback shown and action result].
Include at least: one criterion per core rule from Section C, and one per formula
from Section D. Do NOT write "the system works as designed" — every criterion must
be independently verifiable by a QA tester without reading the GDD.
> **When Section D was not authored** (Formulas optional at this tier because the
> system defines no numeric rule), there are no formulas to cover and the
> criteria come from Section C alone — say so in one line rather than silently
> writing fewer criteria. **If Section D was skipped but Section C states a
> quantity** — a rate, threshold, cost or curve — that is the §1 test being met
> after the fact: stop, tell the user Formulas is required for this system, and
> author it before finalising the criteria. A criterion cannot verify a number
> the GDD never defines.
>
> **That escalation applies at `standard` only.** It re-runs §1's *conditional*
> Formulas test, and §1 disables that conditional at `minimal` outright — *"the
> conditional Formulas rule does NOT re-apply at minimal"*. At `minimal` a
> Section C quantity is expected and does **not** pull Formulas back in: state
> the value inline in Core Rules so it stays implementable, and move on. At
> `full`, Section D is unconditionally required, so the case cannot arise. Read
> without this scope, the two rules contradict each other for any `minimal`
> system that defines a rate — which is most of them.
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Draft the section without the specialist. Add a note: "`qa-lead` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless this is a section with HIGH implementation risk (Sections D and H only). For other sections, draft without the agent.
- `full` → spawn as described below.
**Agent delegation (MANDATORY)**: Spawn `qa-lead` via `Agent` before finalising acceptance criteria. Provide: the completed GDD sections C, D, E, and ask them to validate that the criteria are independently testable and cover all core rules and formulas. Surface any gaps or untestable criteria to the user.
**Questions to ask**:
- What's the minimum set of tests that prove this works?
- What performance budget does this system get? (frame time, memory)
- What would a QA tester check first?
**Cross-reference**: Include criteria that verify cross-system interactions work,
not just this system in isolation.
---
### Optional Sections: Visual/Audio, Game Feel, UI Requirements, Cross-References, Open Questions
These five are the template sections that are **not** among §1's eight. They are
governed here, not by the tier: §1's per-tier lists decide the *required* set,
and this block decides the rest independently. Adding a section here therefore
never changes a tier's section count.
Visual/Audio and Game Feel are **REQUIRED** for some categories — not optional.
Determine the requirement level before asking:
**Keyed on the `Category` column of `systems-index.md`** — the nine values
`templates/systems-index.md` defines. Every one of the nine appears below
exactly once, so nothing falls through:
**Visual/Audio is REQUIRED (mandatory — do not offer to skip) for:**
- `Gameplay` — combat, AI, stealth, movement, interaction: everything the player
sees resolve
- `UI` — HUD, menus, inventory screens, dialogue UI
- `Narrative` — dialogue, quests, cutscenes, lore delivery
- `Audio` — by definition
> **`Gameplay` is the row this table was missing.** It is the category
> `/map-systems` assigns to combat, AI and movement — the largest bucket in most
> action games. If it appears in **neither** this list nor the "all other" list
> below, the skill has no defined behaviour for it and the author has to guess.
> All nine categories must be covered between the two lists.
For required systems: **spawn `art-director` via `Agent`** before drafting this section. Provide: system name, game concept, game pillars, art bible sections 1–4 if they exist. Ask them to specify: (1) VFX and visual feedback requirements for this system's events, (2) any animation or visual style constraints, (3) which art bible principles most directly apply to this system. Present their output; do NOT leave this section as `[To be designed]` for visual systems.
**Review mode check** (apply before spawning):
- `solo` → skip this agent spawn. Draft the section without the specialist. Add a note: "`art-director` not consulted — Solo mode. Review manually before production."
- `lean` → skip unless this system's visual feedback is central to it (a `Gameplay` or `UI` system whose events the player reads to play). Otherwise draft without the agent.
- `full` → spawn as described above.
> Sections B, C, D, E and H each carry this block and this spawn did not, while
> being worded as mandatory (*"do NOT leave this section as `[To be designed]`"*).
> Two agents in `solo` skipped it anyway, on the strength of the other five, and
> both flagged the guess. `director-gates.md`'s *"solo → no director gates
> anywhere"* governs director **gates**, not specialist spawns, so it did not
> settle it — this block does.
**Game Feel is REQUIRED (mandatory — do not offer to skip) for `Gameplay` and
`UI`** — the categories whose systems the player directly operates, where
responsiveness, weight and snap are design targets rather than polish. It is
optional for the other seven. The template argues the point itself: feel *"drives
animation budgets, input handling architecture, and hitbox timing. Retrofitting
feel targets after implementation is expensive."*
**Cross-References is REQUIRED whenever the Dependencies section names another
GDD.** The rule is derived, not category-keyed: if this document references
another system's mechanic, value or rule anywhere, that reference belongs in the
table. Where Dependencies names nothing, write *"None — this system references no
other GDD"* rather than leaving the placeholder. `/review-all-gdds` Phase 2c
reads this table when it exists.
For the remaining five categories — `Core`, `Progression`, `Economy`,
`Persistence`, `Meta` — Visual/Audio is optional: offer the optional sections
after the required sections.
> **At `minimal`, force nothing.** §1 says a voluntary `minimal` GDD is *"exactly
> the 5 standard sections"*, which contradicts a category rule that makes
> Visual/Audio or Game Feel mandatory. §1 wins: at `minimal` both drop to
> optional and the whole set goes through the widget below. The contradiction is
> real — an agent authoring a `minimal` inventory GDD hit it and had to choose.
Use `AskUserQuestion`:
- "The required sections for this workflow tier are complete. Which of the
remaining template sections do you want to define?"
- Options: "All of them", "Just Cross-References and open questions", "Skip — I'll add these later"
- List in the question only the ones still outstanding: Visual/Audio, Game
Feel, UI Requirements, Cross-References, Open Questions **minus** any this
system's category or dependencies already made mandatory above. Offering to
skip a section the rules just made required is how a mandatory section gets
skipped.
- **Recommended option**: "All of them" when the system has any dependency,
UI surface or player-facing feedback; "Just Cross-References and open
questions" otherwise. `autonomous` needs a marked recommendation to pick —
the three options previously carried none, unlike the Section A/B widgets,
so an unattended run had nothing to choose by and defaulted to skipping.
Do **not** state a section count here. The required set is tier-dependent
(§1: 8 at `full`, 5 + conditional Formulas at `standard`, 5 at a voluntary
`minimal`), so the previous hardcoded "8 required sections are complete" was
false on every run below `full` — it told a `standard`-tier user that 8
sections existed when 6 had been authored.
For **Visual/Audio** (non-required systems): Coordinate with `art-director` and `audio-director` if detail is needed. Often a brief note suffices at the GDD stage.
> **Asset Spec Flag**: After the Visual/Audio section is written with real content, output this notice:
> "📌 **Asset Spec** — Visual/Audio requirements are defined. After the art bible is approved, run `/asset-spec system:[system-name]` to produce per-asset visual descriptions, dimensions, and generation prompts from this section."
For **UI Requirements**: Coordinate with `ux-designer` for complex UI systems.
After writing this section, check whether it contains real content (not just
`[To be designed]` or a note that this system has no UI). If it does have real
UI requirements, output this flag immediately:
> **📌 UX Flag — [System Name]**: This system has UI requirements. In Phase 4
> (Pre-Production), run `/ux-design` to create a UX spec for each screen or
> HUD element this system contributes to **before** writing epics. Stories that
> reference UI should cite `design/ux/[screen].md`, not the GDD directly.
>
> Note this in the systems index for this system if you update it.
For **Open Questions**: Capture anything that came up during design that wasn't
fully resolved. Each question should have an owner and target resolution date.
---
@@ -0,0 +1,198 @@
# /design-system — Phase 5: Post-Design Validation
> Part of `/design-system`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 5. Post-Design Validation
**In this file:**
- 5-pre: Author the Summary
- 5a: Self-Check
- 5a-bis: Creative Director Pillar Review
- 5b: Update Entity Registry
- 5c: Offer Design Review
- 5d: Update Systems Index
- 5e: Update Session State
- 5f: Suggest Next Steps
After all sections are written:
### 5-pre: Author the Summary
Write `## Summary` and its `> **Quick reference**` line now — after the design
exists, so the summary distils real content rather than intentions. This runs
**at every tier**, including `standard` and a voluntary `minimal` GDD: the
Summary is what lets a later skill scan 20 GDDs and decide which to read in full
(`/create-epics`, `/architecture-review`, `/review-all-gdds` all grep it), so a
GDD without it silently forces those consumers back to full reads.
- **Summary body**: 2–3 sentences — what this system is, what it does for the
player, why it exists in this game. No jargon; a reader who has not seen the
GDD should learn whether it is relevant to their task.
- **Quick reference**: `Layer` and `Priority` from the systems index
(`design/gdd/systems-index.md`); `Key deps` from the Dependencies section just
written (system names, or `None`).
Replace the `[To be designed]` Summary placeholder in the skeleton. Then apply
the section cycle's Write step as for any other section.
### 5a: Self-Check
Read back the complete GDD from file (not from conversation memory — the file is
the source of truth). Verify:
- The `## Summary` and its Quick reference are populated (not the placeholder)
- Every section **required at this system's effective tier** has real content
(not placeholders) — §1: 8 at `full`, 5 + conditional Formulas at `standard`,
5 at a voluntary `minimal`. Do not verify against a fixed count of 8: below
`full` that reports a correctly-authored GDD as incomplete, which is the same
error already corrected in the optional-sections prompt above
- Formulas reference defined variables
- Edge cases have resolutions
- Dependencies are listed with interfaces
- Acceptance criteria are testable
### 5a-bis: Creative Director Pillar Review
**Review mode check** — apply before spawning CD-GDD-ALIGN:
- `solo` → skip. Note: "CD-GDD-ALIGN skipped — Solo mode." Proceed to Step 5b.
- `lean` → skip (not a PHASE-GATE). Note: "CD-GDD-ALIGN skipped — Lean mode." Proceed to Step 5b.
- `full` → spawn as normal.
Before finalizing the GDD, spawn `creative-director` via `Agent` using gate **CD-GDD-ALIGN** (`.claude/docs/director-gates/cd-gdd-align.md`).
Pass: completed GDD file path, game pillars (from `design/gdd/game-concept.md` or `design/gdd/game-pillars.md`; if there is neither, the pitch and "what they feel" line of `design/game-brief.md`), MDA aesthetics target, and the GDD's Player Fantasy section — or, when this tier did not author one, say so.
Handle verdict per the standard rules in `director-gates.md`.
On `Revise flagged items`, or to resolve a REJECT, each flagged section runs its
section cycle again — its specialist consulted as that section's review-mode
check says — and is re-approved through its "Approve the [Section Name]
section?" widget before the Edit that writes it; then record `REVISED [date]`.
A `NOT ASSESSED` answer is never an approval: name the missing input, then
supply it and re-run the gate, or record `NOT ASSESSED`.
After resolution, record the verdict in the GDD Status header:
`> **Creative Director Review (CD-GDD-ALIGN)**: APPROVED [date] / CONCERNS (accepted) [date] / REVISED [date] / NOT ASSESSED [date] — [missing input]`
---
### 5b: Update Entity Registry
Scan the completed GDD for cross-system facts that should be registered:
- Named entities (enemies, NPCs, bosses) with stats or drops
- Named items with values, weights, or categories
- Named formulas with defined variables and output ranges
- Named constants referenced by value in more than one place
**First check the registry exists** — §2a reads it *"if it exists"*, and this
step never carried the same guard. At `standard` and below the file is often
absent, and a grep against a missing path returns nothing, which is
indistinguishable from "no candidate is registered yet":
- **Absent** — say so, and ask whether to create it:
*"`design/registry/entities.yaml` does not exist. May I create it with these
[N] entries?"* If the user declines, skip 5b and say the registry was not
written — do not treat the skip as a clean pass.
- **Present but empty** — every list is `[]`, or the only matches are inside
comment blocks. Treat it as present, register the candidates, but say which
state you found: *"registry exists and is empty — all [N] entries are new."*
The shipped template's comments carry fully-formed examples referencing
`design/gdd/inventory.md` with real-looking values (`base_inventory_slots: 20`,
`gold_carry_limit: 9999`), so §2a's registry greps return **comment
lines** on an empty registry — and §2d would then present those invented numbers to the user as
*"These values are locked."* Match entries under a live `entities:`/`items:`/
`formulas:`/`constants:` key, never a commented example.
- **Present** — for each candidate, check whether it is already registered:
```
Grep pattern=" - name: [candidate_name]" path="design/registry/entities.yaml"
```
Present a summary:
```
Registry candidates from this GDD:
NEW (not yet registered):
- [entity_name] [entity]: [attribute]=[value], [attribute]=[value]
- [item_name] [item]: [attribute]=[value], [attribute]=[value]
- [formula_name] [formula]: variables=[list], output=[min–max]
ALREADY REGISTERED (referenced_by will be updated):
- [constant_name] [constant]: value=[N] ← matches registry ✅
```
Ask: "May I update `design/registry/entities.yaml` with these [N] new entries
and update `referenced_by` for the existing entries?" (If the file was absent
and the user approved creating it, the wording is *create*, not *update*, and
there are no `referenced_by` arrays to merge.)
If yes: append new entries and update `referenced_by` arrays. Never modify
existing `value` / attribute fields without surfacing it as a conflict first.
### 5c: Offer Design Review
Present a completion summary:
> **GDD Complete: [System Name]**
> - Sections written: [list]
> - Provisional assumptions: [list any assumptions about undesigned dependencies]
> - Cross-system conflicts found: [list or "none"]
> **To validate this GDD, open a fresh Claude Code session and run:**
> `/design-review design/gdd/[system-name].md`
>
> **Never run `/design-review` in the same session as `/design-system`.** The reviewing
> agent must be independent of the authoring context. Running it here would inherit
> the full design history, making independent critique impossible.
**NEVER offer to run `/design-review` inline.** Always direct the user to a fresh window.
### 5d: Update Systems Index
After the GDD is complete (and optionally reviewed):
**First check the systems index exists.** §2a skips it at `minimal` because it is
never written at that tier, and this step never carried the same guard — the same
class of bug §5b was patched for. It bites hardest on a `minimal` project with a
`system_overrides` bump, where the effective tier is `standard` or `full` and
nothing else in §5 hints the file may be absent.
- **Absent** — say so in one line (*"no `design/gdd/systems-index.md` at this
workflow tier; nothing to update"*) and skip to §5e. Do **not** offer to create
one: `/map-systems` owns that file, and a stub written here would be a systems
index listing exactly one system.
- **Present** — continue:
- Read the systems index
- Update the target system's row:
- If design-review was run and verdict is APPROVED: Status → "Approved"
- If design-review was run and verdict is NEEDS REVISION or MAJOR REVISION NEEDED: Status → "Needs Revision" (that exact string — `/design-review` sets "In Review" only once the revisions are applied)
- If design-review was skipped: Status → "Designed" (pending review)
- If the user chose "I'll review it myself first": Status → "Designed"
- Design Doc: link to `design/gdd/[system-name].md`
- Update the Progress Tracker counts
Ask: "May I update the systems index at `design/gdd/systems-index.md`?"
### 5e: Update Session State
Update `production/session-state/active.md` with:
- Task: [system-name] GDD
- Status: Complete (or In Review if design-review was run)
- File: design/gdd/[system-name].md
- Sections: [list the sections actually authored, by name] — **never a fixed
count**; §5a forbids verifying against `/8`, and the same reasoning applies to
recording it. Below `full` a correctly-authored GDD has fewer than 8 sections,
and writing "All 8 written" into session state makes the next reader believe
a complete GDD is incomplete
- Next: [suggest next system from design order]
### 5f: Suggest Next Steps
Use `AskUserQuestion`:
- "What's next?"
- Options:
- "Run `/consistency-check` — verify this GDD's values don't conflict with existing GDDs (recommended before designing the next system)"
- "Design next system ([next-in-order])" — if undesigned systems remain
- "Fix review findings" — if design-review flagged issues
- "Stop here for this session"
- "Run `/gate-check`" — if enough MVP systems are designed
---
+6 -521
View File
@@ -13,7 +13,6 @@ model: sonnet
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
@@ -74,541 +73,27 @@ If not found, ask: "Which story are we implementing?" Glob
## Phase 2: Load Full Context
**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 — `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." 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 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
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
- **Out of Scope** boundaries
- **Test Evidence** — the required test file path
- **Dependencies** — what must be DONE before this story
### The TR registry
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
**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 status and freshness with one line, not one file.** Resolve the ADR path
from the story, then:
```
Grep pattern="^## (Status|Last Verified|Date)" path="docs/architecture/[adr-file].md" output_mode="content" -A 2
```
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 |
|---|---|---|
| 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." |
| 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
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, 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. 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,
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 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.
### The control manifest
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
Check: does the story's embedded Manifest Version match the current manifest header date?
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 (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.
If [B]: edit the story file's `Manifest Version:` field to the current manifest date AND add a `Manifest-Note: Proceeded with old manifest rules on [date] — non-compliance risk accepted.` line to the story header. Read the manifest for new rules anyway. Note the decision in the Phase 6 summary under "Deviations". `/story-done` will include the Manifest-Note in its deviations section without re-checking staleness.
If [C]: stop. Do not spawn any agent. Let the user review and re-run `/dev-story`.
### Dependency validation
After extracting the **Dependencies** list from the story file, validate each:
1. Glob `production/epics/**/*.md` to find each dependency story file.
2. Read its `Status:` field.
3. If any dependency has Status other than `Complete` or `Done`:
- Use `AskUserQuestion`:
- Prompt: "Story '[current story]' depends on '[dependency title]' which is currently [status], not Complete. How do you want to proceed?"
- Options:
- `[A] Proceed anyway — I accept the dependency risk`
- `[B] Stop — I'll complete the dependency first`
- `[C] The dependency is done but status wasn't updated — mark it Complete and continue`
- If [B]: set story status to **BLOCKED** in session state and stop. Do not spawn any programmer agent.
- If [C]: ask "May I update [dependency path] Status to Complete?" before continuing.
- If [A]: note in Phase 6 summary under "Deviations": "Implemented with incomplete dependency: [dependency title] — [status]."
If a dependency file cannot be found: warn "Dependency story not found: [path]. Verify the path or create the story file."
---
### Engine reference
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
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.
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.
---
**Read `references/2-load-context.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 3: Route to the Right Programmer
Based on the story's **Layer**, **Type**, and **system name**, determine which
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.
### Primary agent routing table
| Story context | Primary agent |
|---|---|
| Foundation layer — any type | `engine-programmer` |
| Any layer — Type: UI | `ui-programmer` |
| Any layer — Type: Visual/Feel | `gameplay-programmer` (implements) |
| Core or Feature — gameplay mechanics | `gameplay-programmer` |
| Core or Feature — AI behaviour, pathfinding | `ai-programmer` |
| Core or Feature — networking, replication | `network-programmer` |
| Config/Data — no code | No agent needed (see Phase 4 Config note) |
### Engine specialist — always spawn as secondary for code stories
**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-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. `/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.
---
**Read `references/3-route.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 4: Implement
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 `Agent` prompt. The agent reads what it needs directly.
> **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 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
> 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), 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
> 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 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 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:
- 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
### 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, 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
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`.
---
**Read `references/4-implement.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 5: Test Evidence Requirements
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.
**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. **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). 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.*
>
> 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 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.
---
**Read `references/5-test-evidence.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 6: Collect and Summarise
### 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 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.
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`.
**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.
**`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)
- **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
Present a concise implementation summary:
```
## Implementation Complete: [Story Title]
**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 (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`
**Acceptance criteria covered**:
- [x] [criterion] — implemented in [file:function]
- [x] [criterion] — covered by test [test_name]
- [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. *(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: `/story-done [story-path]` — at `standard`/`full`, `/code-review [file1] [file2]` first
```
---
**Read `references/6-collect.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 7: Update Session State
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:
```
<!-- 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 -->
```
**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."
---
**Read `references/7-session-state.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Error Recovery Protocol
@@ -0,0 +1,193 @@
# /dev-story — Phase 2: Load Full Context
> Part of `/dev-story`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 2: Load Full Context
**In this file:**
- The story file
- The TR registry
- The governing ADR
- The control manifest
- Dependency validation
- Engine reference
- Mark Story In Progress
**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 — `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." 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 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
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
- **Out of Scope** boundaries
- **Test Evidence** — the required test file path
- **Dependencies** — what must be DONE before this story
### The TR registry
Grep the story's TR-ID from `docs/architecture/tr-registry.yaml`
(`Grep pattern="id: <TR-ID>\s*$" 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
**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 status and freshness with one line, not one file.** Resolve the ADR path
from the story, then:
```
Grep pattern="^## (Status|Last Verified|Date)" path="docs/architecture/[adr-file].md" output_mode="content" -A 2
```
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 |
|---|---|---|
| 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." |
| 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
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, 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. 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,
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 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.
### The control manifest
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
Check: does the story's embedded Manifest Version match the current manifest header date?
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 (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.
If [B]: edit the story file's `Manifest Version:` field to the current manifest date AND add a `Manifest-Note: Proceeded with old manifest rules on [date] — non-compliance risk accepted.` line to the story header. Read the manifest for new rules anyway. Note the decision in the Phase 6 summary under "Deviations". `/story-done` will include the Manifest-Note in its deviations section without re-checking staleness.
If [C]: stop. Do not spawn any agent. Let the user review and re-run `/dev-story`.
### Dependency validation
After extracting the **Dependencies** list from the story file, validate each:
1. Glob `production/epics/**/*.md` to find each dependency story file.
2. Read its `Status:` field.
3. If any dependency has Status other than `Complete` or `Done`:
- Use `AskUserQuestion`:
- Prompt: "Story '[current story]' depends on '[dependency title]' which is currently [status], not Complete. How do you want to proceed?"
- Options:
- `[A] Proceed anyway — I accept the dependency risk`
- `[B] Stop — I'll complete the dependency first`
- `[C] The dependency is done but status wasn't updated — mark it Complete and continue`
- If [B]: set story status to **BLOCKED** in session state and stop. Do not spawn any programmer agent.
- If [C]: ask "May I update [dependency path] Status to Complete?" before continuing.
- If [A]: note in Phase 6 summary under "Deviations": "Implemented with incomplete dependency: [dependency title] — [status]."
If a dependency file cannot be found: warn "Dependency story not found: [path]. Verify the path or create the story file."
---
### Engine reference
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
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.
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.
---
@@ -0,0 +1,89 @@
# /dev-story — Phase 3: Route to the Right Programmer
> Part of `/dev-story`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 3: Route to the Right Programmer
Based on the story's **Layer**, **Type**, and **system name**, determine which
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.
### Primary agent routing table
| Story context | Primary agent |
|---|---|
| Foundation layer — any type | `engine-programmer` |
| Any layer — Type: UI | `ui-programmer` |
| Any layer — Type: Visual/Feel | `gameplay-programmer` (implements) |
| Core or Feature — gameplay mechanics | `gameplay-programmer` |
| Core or Feature — AI behaviour, pathfinding | `ai-programmer` |
| Core or Feature — networking, replication | `network-programmer` |
| Config/Data — no code | No agent needed (see Phase 4 Config note) |
### Engine specialist — always spawn as secondary for code stories
**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-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. `/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.
---
@@ -0,0 +1,68 @@
# /dev-story — Phase 4: Implement
> Part of `/dev-story`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 4: Implement
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 `Agent` prompt. The agent reads what it needs directly.
> **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 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
> 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), 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
> 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 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 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:
- 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
### 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, 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
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`.
---
@@ -0,0 +1,74 @@
# /dev-story — Phase 5: Test Evidence Requirements
> Part of `/dev-story`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 5: Test Evidence Requirements
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.
**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. **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). 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.*
>
> 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 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.
---
@@ -0,0 +1,113 @@
# /dev-story — Phase 6: Collect and Summarise
> Part of `/dev-story`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 6: Collect and Summarise
**In this file:**
- First: did the agent actually finish?
- Then 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 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.
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`.
**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.
**`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)
- **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
Present a concise implementation summary:
```
## Implementation Complete: [Story Title]
**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 (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`
**Acceptance criteria covered**:
- [x] [criterion] — implemented in [file:function]
- [x] [criterion] — covered by test [test_name]
- [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. *(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: `/story-done [story-path]` — at `standard`/`full`, `/code-review [file1] [file2]` first
```
---
@@ -0,0 +1,40 @@
# /dev-story — Phase 7: Update Session State
> Part of `/dev-story`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 7: Update Session State
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:
```
<!-- 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 -->
```
**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."
---
+3 -1
View File
@@ -7,6 +7,8 @@ allowed-tools: Read, Glob, Grep
model: sonnet
---
# Estimate
## Phase 1: Understand the Task
Read the task description from the argument. If the description is too vague to estimate meaningfully, ask for clarification before proceeding.
@@ -125,7 +127,7 @@ This skill is read-only — no files are written. Verdict: **COMPLETE** — esti
- If confidence is Low: recommend a time-boxed spike (`/prototype`) before committing.
- If the task is > 10 days: recommend breaking it into smaller stories via `/create-stories`.
- To schedule the task: run `/sprint-plan update` to add it to the next sprint.
- To schedule the task: run `/sprint-plan update` to add it to the next sprint (if the project has no sprint plan, as on the default minimal workflow, add it to the brief's build order instead).
### Guidelines
+12 -745
View File
@@ -12,7 +12,6 @@ model: opus
Resolved above — use as-is; `--review` overrides `review_mode`. No block →
defaults in `.claude/docs/config-resolution.md`.
# Phase Gate Validation
This skill validates whether the project is ready to advance to the next development
@@ -41,7 +40,6 @@ The project progresses through these stages:
**Target phase:** `$ARGUMENTS` with any `--review <mode>` pair removed (blank = auto-detect current stage, then validate next transition). `/gate-check --review full` names no phase.
Note: in `solo` mode, director spawns (CD-PHASE-GATE, TD-PHASE-GATE, PR-PHASE-GATE, AD-PHASE-GATE) are skipped — gate-check becomes artifact-existence checks only. In `lean` mode, the phase-gate directors still run (phase gates are the purpose of lean mode); how many of them run is set by `workflow` below.
**`workflow`** (per `.claude/docs/workflow-modes.md`):
@@ -104,770 +102,39 @@ transition; never load the others.**
| Gate | Definition file |
|------|-----------------|
| Concept → Systems Design | `.claude/skills/gate-check/references/gate-systems-design.md` |
| Systems Design → Technical Setup | `.claude/skills/gate-check/references/gate-technical-setup.md` |
| Technical Setup → Pre-Production | `.claude/skills/gate-check/references/gate-pre-production.md` |
| Pre-Production → Production | `.claude/skills/gate-check/references/gate-production.md` |
| Production → Polish | `.claude/skills/gate-check/references/gate-polish.md` |
| Polish → Release | `.claude/skills/gate-check/references/gate-release.md` |
| Concept → Systems Design | `references/gate-systems-design.md` |
| Systems Design → Technical Setup | `references/gate-technical-setup.md` |
| Technical Setup → Pre-Production | `references/gate-pre-production.md` |
| Pre-Production → Production | `references/gate-production.md` |
| Production → Polish | `references/gate-polish.md` |
| Polish → Release | `references/gate-release.md` |
Each file states the `full` baseline first, then the `standard` and `minimal`
reductions for that gate. Apply the tier resolved in Section 1.
## 2b. Workflow Tier Adjustment
Each gate file carries its own tier reductions (see Section 2). Two rules apply
across all of them:
> **How to apply:** run the loaded gate's checklist, then apply that file's tier
> reduction for the tier resolved in Section 1. **drop** = not checked at this
> tier; **→ recommended** = absent surfaces as CONCERNS, never a Blocker; items
> not named keep their baseline status. Reductions only ever *relax* a
> requirement — the only thing that adds one is `workflow_overrides` (below).
>
> **`qa.level` (Section 1) further relaxes the test items independently of the
> tier:** at `qa.level: minimal` the test-evidence / unit-test items become
> non-required at every workflow tier (so even `workflow: full` does not require
> them); the Section 3 `testing.strict` check is then a no-op.
>
> **It relaxes tests, not the look.** A UI story's retained screenshots, and a
> Visual/Feel story's screenshots plus lead sign-off, are required at every
> `qa.level` wherever the gate file asks for story evidence
> (`.claude/docs/coding-standards.md`: tests are waived at `minimal`, the look
> is not).
>
> **The smoke check is excluded from that relaxation, and is the floor.**
> `qa.level` relaxes *per-story test evidence*; a smoke check is **build health**,
> not story evidence, and the two are already held apart on exactly this basis in
> `.claude/docs/coding-standards.md` ("`/smoke-check` is a build-health gate, not
> a per-story evidence gate ... This divergence is intentional"). So a gate file
> that requires a smoke report keeps requiring it at every `qa.level`.
>
> Without that exclusion the Production → Polish gate had **zero required
> artifacts at `rigor: minimal`** and could not fail on artifacts by
> construction: `minimal` reduced the gate to the smoke check alone, `qa.level`
> then dropped the smoke check too, and one `modes.rigor` setting fires both.
> **A gate with no required artifacts left must say so, and may not return
> PASS.** After applying the tier reduction and the `qa.level` relaxation, count
> what remains required. If the count is zero, report
> **NOT ASSESSED** naming both reducers and the gate — *"Production → Polish at
> `workflow: minimal` + `qa.level: minimal` leaves no required artifact; this
> gate verified nothing"* — rather than a PASS earned by having nothing to check.
> Per `.claude/rules/skill-authoring.md` obligation 1, a run that could not
> assess its scope has not established that the scope is good, and obligation 3
> requires the emptiness to be visible in the output rather than inferable from
> a silent green.
>
> **The one exception: a gate its tier reference file marks "not applicable" at
> this tier** (Systems Design → Technical Setup at `workflow: minimal`). That is
> not a gate with nothing left to check but a transition the tier does not have:
> it PASSes with that file's note, printed in the report. The director panel
> does not run for it — note "Director Panel skipped — gate not applicable at
> `workflow: [tier]`" — and the Section 6 stage write still asks first.
>
> **`performance.enforce` is likewise independent of the tier, and a tier
> reduction never suppresses it.** The performance check in Section 3 runs at
> every workflow tier, and `block` makes a breach a Blocker at every workflow
> tier. Do **not** read a gate file's *"everything else drops"* as dropping it:
> `off` is the only thing that makes budgets informational, and it is a
> deliberate choice the user makes on the same key.
>
> Without this, `performance.enforce: block` is **inert on every `rigor: minimal`
> project** — the Polish gate's `minimal` reduction drops everything outside its
> floor, and "Performance is within budget" sits in the dropped remainder. A
> setting that works only when a rule is disregarded is not wired.
### Per-system overrides (`workflow_overrides.system_overrides`)
Independent of the project-level tier above, and applied **only** on the gates
that validate MVP GDDs (Systems Design → Technical Setup, and the GDD-completeness
checks at Pre-Production → Production). For each system, resolve its effective
tier:
1. If the block's `system_overrides` lists `<system>` → that tier
2. Else the project-level `workflow`
**Before applying any of them, check the block the other way round: does every
KEY match a system?** `<system>` is the GDD filename stem
(`.claude/docs/workflow-modes.md`), so for each key in `system_overrides`, look
for `design/gdd/<key>.md`. Any key with no matching stem is reported, naming the
key and listing the stems that do exist:
> `system_overrides key 'no-such-system' matches no GDD in design/gdd/. Available stems: combat, inventory, hammer-heat-system. This override is doing nothing.`
Surface it as a **CONCERNS**-level finding, not a Blocker — the project is still
gateable, but an override the user believes is in force and is not is exactly how
a documented escape hatch silently stops working.
> **This is the one site that performs the check.** `workflow-modes.md:72` says
> *"a key that matches no system is an error, not a no-op"*, and this is the only
> skill that implements it — the three story skills resolve only in the
> system → override direction, so an orphan key is never looked up and
> never noticed. `/gate-check` is the right home: it already resolves the whole
> block, and it is the project-wide audit rather than a per-story one.
Validate each GDD against its own effective tier's section count:
- A system pinned **higher** than the project (e.g. `system_overrides.combat:
full` on a `standard` project) **blocks the gate** until that system's GDD
meets the higher bar (combat → all 8 sections). This is the one case where a
per-system setting makes the gate *stricter* than the project tier.
- A system pinned **lower** (e.g. `inventory: minimal`) relaxes only that system
— its GDD is checked at the lower tier; every other system stays at the project
level. A system pinned **`minimal` imposes no GDD section requirement at all**
(`minimal` = "game brief replaces GDDs" — `.claude/docs/workflow-modes.md`): it
never blocks the gate on a missing or incomplete GDD. Do not invent an
"acceptance-criteria-only" floor for it — there is none.
> **Additive overrides (the only things that make the gate stricter).**
> - `workflow_overrides.art_bible_strict: true` forces the complete (9-section)
> art bible at the Technical Setup → Pre-Production and Pre-Production →
> Production gates regardless of tier or whether visual-asset stories exist.
> - `workflow_overrides.edge_cases: true` and `workflow_overrides.tuning_knobs:
> true` force those GDD sections required when validating GDD completeness,
> additive on top of the resolved tier (e.g. at `standard`, `tuning_knobs: true`
> makes the otherwise-optional Tuning Knobs section blocking). These never
> relax — a `false` value is the default/no-op, never a way to drop a section
> the tier already requires.
---
**Read `references/2b-workflow-tier.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 3. Run the Gate Check
**Before running artifact checks**, read `docs/consistency-failures.md` if it exists.
Extract entries whose Domain matches the target phase (e.g., if checking
Systems Design → Technical Setup, pull entries in Economy, Combat, or any GDD domain;
if checking Technical Setup → Pre-Production, pull entries in Architecture, Engine).
Carry these as context — recurring conflict patterns in the target domain warrant
increased scrutiny on those specific checks.
For each item in the target gate:
### Artifact Checks
**Resolve existence and counts deterministically — do not open files to find out
what exists:**
```
Bash: bash .claude/scripts/artifact-check.sh --phase [source-phase]
```
Pass the phase being advanced *from* (its steps are the work that must be
complete): `systems-design` for the Systems Design → Technical Setup gate,
`pre-production` for Pre-Production → Production, and so on.
At `workflow: minimal`, also run
`bash .claude/scripts/artifact-check.sh --path minimal`: the brief and stories
live on that path, not on any phase, and its `game-brief` and `create-stories`
rows are this tier's floor.
It reads `workflow-catalog.yaml` — which already encodes each step's `glob`,
`pattern`, `min_count` and `any_of` — and reports per step:
| status | Meaning |
|---|---|
| `PRESENT` | glob matched, `min_count` met, `pattern` found where specified |
| `ABSENT` | nothing matched |
| `SHORT` | matched but fewer than `min_count` (`count=` and `min=` given) |
| `PATTERN_MISS` | files exist but none contains the required marker |
| `NO_CHECK` | the step declares no artifact — **not detectable from disk** |
It emits observations, never a verdict: **you** apply the workflow tier and the
required/optional split from Section 2. An `ABSENT` required artifact is a
blocker at `full` and frequently not one at `minimal`; the script does not know
that and does not decide it.
**`NO_CHECK` is not `PRESENT`.** The header prints a `NO_CHECK:` count before any
row precisely so this cannot be skimmed past. Those steps were *scanned*, not
*satisfied* — carry each into Section 4 (Collaborative Assessment) and ask, or
mark MANUAL CHECK NEEDED. A gate that reports PASS because most of its checklist
was undetectable is the failure mode this count exists to prevent.
**Existence is not adequacy.** The script cannot tell a real document from a
template skeleton. So: for any artifact the verdict actually turns on, spot-read
it and confirm it has real content — the same escalation rule the
`gdd-structure-check.sh` step below uses. Do not spot-read artifacts the verdict
does not turn on.
> **A smoke report is always an artifact the verdict turns on — spot-reading it
> is mandatory, not discretionary.** At `minimal` it is frequently the *only*
> required artifact, so the whole gate rests on one file that nothing generated
> and nothing verifies. Check its claims against the repo, and raise any that the
> tree contradicts:
>
> - It reports a passing automated suite → the engine's test root must actually
> contain test files and the project must have a runner. "24 passed, 0 failed"
> in a repo with no test files under that root — `tests/unit/` and
> `tests/integration/` on Godot, `Assets/Tests/` on Unity,
> `Source/<Module>/Private/Tests/` on Unreal — and no runner is a finding, not
> evidence.
> - It marks a critical path PASS → the code for that path must exist in the code
> root. A PASS on "banking ends the run" with no banking code is a finding.
> - It carries no date, or predates the newest commit touching the code root →
> say so; a stale smoke report describes a build that no longer exists.
>
> Report a contradiction at the same level the artifact was required at: a
> Blocker where the smoke check is required, CONCERNS where it is recommended.
> Existence plus a verdict-line grep would clear a fabricated report.
For code checks, verify directory structure and file counts.
**Systems Design → Technical Setup gate — cross-GDD review check**:
Use `Glob('design/gdd/gdd-cross-review-*.md')` to find the `/review-all-gdds` report.
If no file matches: at `full` mark the "cross-GDD review report exists" artifact as
**FAIL** and surface it prominently ("No `/review-all-gdds` report found in
`design/gdd/`. Run `/review-all-gdds` before advancing to Technical Setup."); at
`standard` the report is recommended, so mark it **CONCERNS**, not a blocker; at
`minimal` this gate is not applicable (see the gate file). If a file is found, read it and
check the verdict line: a FAIL verdict means the cross-GDD consistency check failed
and must be resolved before advancing. A NOT ASSESSED verdict means that review
could not compare the GDDs, so it satisfies nothing here: mark the item NOT
ASSESSED for this gate, never passed.
### Quality Checks
- For test checks: Run the test suite via `Bash` if a test runner is configured.
**If no runner is configured, that is `NOT ASSESSED`, not a silent skip** — see
the trigger in the verdict section. A gate that ran no tests found no test
failures, which is not the same as passing.
A test failure's effect on the verdict depends on the `testing.strict` block
**resolved in Phase 1** (`resolve_config` merges `project.local.yaml` over
`project.yaml`; reading the file directly would drop a local override), per
test type:
- **Logic** — unit-level failures (`tests/unit/` on Godot, Edit Mode on
Unity), gated by `testing.strict.logic`.
- **Integration** — failures in `tests/integration/` on Godot, Play Mode on
Unity, gated by `testing.strict.integration`. On Unreal, where one root
(`Source/<Module>/Private/Tests/`) holds both, classify a failure by its
story's Type, or apply the stricter of the two levels when that is unknown.
- For each type: take `testing.strict.<type>` from that block; use it only
if its value is `true` or `false` (case-insensitive). If the key is absent,
empty, or holds any other value, read `testing.strict` as a plain boolean
(legacy single-value form); if that too is absent or invalid, default to
`true` (Logic and Integration are both strict by default — behavior unchanged
from before this setting existed). Surface any unrecognized value to the user.
- At a strict (`true`) gate level, failures of that type are **Blockers**
(verdict FAIL). At an advisory (`false`) level, they are **Concerns**
(verdict minimum CONCERNS, not FAIL) — list them under Recommendations, not
Blockers.
- For design review checks, gather section presence **deterministically** — do not
read the GDDs to count headings:
```
Bash: bash .claude/scripts/gdd-structure-check.sh
```
It prints a `PRESENT:` / `ABSENT:` pair per GDD and already accepts
`## Detailed Design` as satisfying the `Detailed Rules` requirement. It reports
presence only and makes no REQUIRED/ADVISORY judgment.
Then apply each GDD's **effective tier** (per-system resolution below) to those
lists — all 8 sections at `full`, the 5 standard sections (+ conditional
Formulas) at `standard`. A missing *required* section blocks; a missing section
that is optional at the effective tier is advisory. A section reported PRESENT
can still fail review if it is an empty heading — spot-read any section the
verdict actually turns on.
- For performance checks: read the budgets (`performance.target_framerate`,
`frame_budget_ms`, `draw_call_limit`, `memory_ceiling_mb`) from `project.yaml`
(else technical-preferences.md) and compare against any profiling data in
`tests/performance/` or recent `/perf-profile` output. What a breach *means*
is set by `performance.enforce`, taken from the Phase 1 resolved block (it is
locally overridable, so do not read the file for this one):
- `warn` (default) — breaches are **CONCERNS**, never Blockers.
- `block` — breaches are **Blockers** from the Polish gate onward.
- `off` — budgets are informational; do not surface breaches in the verdict.
Only these three values are recognized. Surface anything else to the user and
fall back to `warn` rather than guessing.
- For localization checks: `Grep` for hardcoded strings in the **code root** (resolve per `.claude/docs/code-root-resolution.md`). **If the code root is unresolved, report `NOT ASSESSED — code root unresolved` rather than zero hits.**
### Cross-Reference Checks
- Compare `design/gdd/` documents against implementations in the **code root**
- Check that every system referenced in architecture docs has corresponding code
- Verify sprint plans reference real work items
---
**Read `references/3-run-gate-check.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 4. Collaborative Assessment
For items that can't be automatically verified, **ask the user**:
- "I can't automatically verify that the core loop plays well. Has it been playtested?"
- "No playtest report found. Has informal testing been done?"
- "Performance profiling data isn't available. Would you like to run `/perf-profile`?"
**Never assume PASS for unverifiable items.** Mark them as MANUAL CHECK NEEDED.
An answer resolves the item: "no" or "not yet" is a checked, failed item
(CONCERNS or FAIL, naming the skill that closes it — `/design-review [doc]` for
an unreviewed concept or GDD) — except a play question at the Production gate
(a human has played the Vertical Slice; at `minimal`, the core loop is fun on
the current build), where "not yet" means nobody has played it: NOT ASSESSED
(`gate-production.md`). Only an unanswered item or "I don't know" stays
MANUAL CHECK NEEDED, which Section 5 turns into NOT ASSESSED.
This applies to questions about the project's state. Declining an offer to
produce missing data (e.g. `/perf-profile`) leaves the item NOT ASSESSED; at
`performance.enforce: off` it stays out of the verdict.
---
## 4b. Director Panel Assessment
The panel is set by **two independent axes**, both resolved in Phase 1: `review_mode`
decides *whether* the panel runs, `workflow` decides *how wide* it is.
**Axis 1 — `review_mode` decides whether any director spawns:**
- `solo` → skip the panel entirely. Note in output: "Director Panel skipped — Solo mode. Gate verdict based on artifact and quality checks only." Proceed to Phase 5.
- `lean` → run the panel (phase gates always run in lean mode — this is their purpose).
- `full` → run the panel.
**Axis 2 — `workflow` decides the panel width.** Directors are Opus-tier, so a
fixed four-director panel costs a two-system jam exactly what it costs a
thirty-system commercial project. The gate still runs at every tier; only its
breadth scales:
| `workflow` | Panel | Directors |
|---|---|---|
| `minimal` | 1 | `producer` |
| `standard` | 2 | `technical-director`, `producer` |
| `full` | 4 | `creative-director`, `technical-director`, `producer`, `art-director` |
`producer` is in every panel — scope and schedule readiness is the one judgment
no tier makes optional. `technical-director` joins at `standard` because that is
the first tier requiring architecture artifacts. `creative-director` and
`art-director` join at `full`, the only tier requiring the full art bible and
UX spec set for them to assess.
> **Width is not the same as strictness.** A narrower panel does not soften the
> verdict: the escalation rule in `.claude/docs/director-gates.md` is unchanged —
> the strictest verdict returned by *whoever ran* still wins. Do not infer PASS
> from a perspective that was never consulted.
Before generating the final verdict, spawn the directors for the resolved tier as **parallel subagents** via `Agent` using the parallel gate protocol from `.claude/docs/director-gates.md`. Issue all the `Agent` calls simultaneously — do not wait for one before starting the next.
**Gate IDs:**
1. **`creative-director`** — gate **CD-PHASE-GATE** (`.claude/docs/director-gates/cd-phase-gate.md`)
2. **`technical-director`** — gate **TD-PHASE-GATE** (`.claude/docs/director-gates/td-phase-gate.md`)
3. **`producer`** — gate **PR-PHASE-GATE** (`.claude/docs/director-gates/pr-phase-gate.md`)
4. **`art-director`** — gate **AD-PHASE-GATE** (`.claude/docs/director-gates/ad-phase-gate.md`)
Pass to each the target phase name, the resolved `workflow` tier, the target
gate's required and recommended artifacts at the resolved tier (the loaded gate
file's checklist after its tier reduction and the `qa.level` relaxation — what
this gate asks for, not what a later one will), the list of artifacts present,
and its gate's own context — named here, so this session never has to read the
gate files:
- **CD-PHASE-GATE**: the game pillars and core fantasy (from
`design/gdd/game-concept.md`, else `design/game-brief.md`).
- **TD-PHASE-GATE**: the architecture document path, the engine reference path
(`docs/engine-reference/<engine>/VERSION.md`), and the ADR list.
- **PR-PHASE-GATE**: the sprint and milestone artifacts present, `team.size` as
resolved above (with the current sprint plan's capacity, if a plan exists), and
the number of stories under `production/epics/` whose status is `Blocked`. At
`workflow: minimal`, pass the Build order in `design/game-brief.md` as the plan — that
tier has no sprint plan.
- **AD-PHASE-GATE**: the art and visual artifacts present, the Visual Identity
Anchor (from `design/gdd/game-concept.md`, else the "Art & audio direction"
line of `design/game-brief.md`), and the art bible path.
Pass each context item as one of three things, so no director has to guess:
- **Present** — its path or value (`0` blocked stories is a value).
- **"none"** — the target gate (or an earlier one) requires or recommends it at
this tier and it does not exist (no architecture document at
`/gate-check pre-production`). For the director that is a fact about the
project to judge, not a missing input.
- **"not expected before [phase]"** — the target gate does not ask for it yet;
name the phase whose gate first does (the architecture document and ADRs
before Pre-Production, the sprint plan before Production). One this tier never
requires is "not required at `workflow: [tier]`" (any sprint plan at
`minimal`). Neither is ever passed as "none", and neither is a finding — a
director judges readiness for the phase being entered, not a later one.
**Name the omissions in the output.** Below the Director Panel summary, when the
panel ran narrower than four, state which perspectives did not run and how to get
them — e.g. "Panel: 2 of 4 (`workflow: standard`). Creative and Art perspectives
not consulted. Raise `modes.rigor` to `full` (or set `modes.workflow: full`) for
the complete panel." Name the setting the config block shows as `workflow`'s
source: when `modes.workflow` is set on its own, raising `modes.rigor` does not
change it. Never point to `--review full` for this — `--review` decides whether
the panel runs, not how wide it is. A silently narrow panel reads as a clean bill
of health from reviewers who never looked.
**Collect every response from the directors that ran, then present the Director Panel summary** (one row per director that ran; name the ones `workflow` left out):
```
## Director Panel Assessment
Creative Director: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
Technical Director: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
Producer: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
Art Director: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
```
**Apply to the verdict:**
- Any director returns NOT READY → verdict is minimum FAIL (no override turns a FAIL into a stage change — Section 6)
- Any director returns CONCERNS → verdict is minimum CONCERNS
- Any director returns NOT ASSESSED (and none returned NOT READY or CONCERNS) → verdict at best NOT ASSESSED; name the input that director said was missing — it never counts as READY
- Every director that ran returns READY → eligible for PASS (still subject to artifact and quality checks from Section 3)
---
**Read `references/4-assessment.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 5. Output the Verdict
```
## Gate Check: [Current Phase] → [Target Phase]
**Date**: [date]
**Checked by**: gate-check skill
### Required Artifacts: [X/Y present]
- [x] design/gdd/game-concept.md (design/game-brief.md at `minimal`) — exists, 2.4KB
- [ ] docs/architecture/ — MISSING (no ADRs found)
- [x] production/sprints/ — exists, 1 sprint plan
### Quality Checks: [X/Y passing]
- [x] GDD has 8/8 required sections
- [ ] Tests — FAILED (3 failures in tests/unit/)
- [?] Core loop playtested — MANUAL CHECK NEEDED
### Blockers
1. **No Architecture Decision Records** — Run `/architecture-decision` to create one
covering core system architecture before entering production.
2. **3 test failures** — Fix failing tests in tests/unit/ before advancing.
### Recommendations
- [Priority actions to resolve blockers]
- [Optional improvements that aren't blocking]
### Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
- **PASS**: All required artifacts present, all quality checks passing
- **CONCERNS**: Minor gaps exist but can be addressed during the next phase —
the stage advances only if the user explicitly accepts them (Section 6)
- **FAIL**: Critical blockers must be resolved before advancing
- **NOT ASSESSED**: One or more required checks could not be run at all — name
which, and why, in the Blockers section
### Accepted Risks (only when the user advanced on CONCERNS)
- [each concern, as listed above] — accepted by the user, [date]
```
**`NOT ASSESSED` — when the gate could not look.** Rank: it **outranks PASS**
(a gate that could not check part of its scope has not established the phase is
ready) and **ranks below CONCERNS and FAIL** (a known blocker is more actionable
than an unknown, and demoting it behind an access problem buries it). It is not a
softer FAIL: "I checked and found a blocker" and "I could not check" need
different fixes — one needs work done, the other needs the input produced or made
readable.
**Verdict precedence — first matching rule wins**, evaluated in this order:
**FAIL**, then **CONCERNS**, then **NOT ASSESSED**, then **PASS**. A gate with
both a real blocker and an unassessable check is FAIL: the blocker is the
actionable finding. Stating the order mechanically removes the inference — the
rank sentence above says what outranks what, but only an ordered list says what
to do when two conditions hold at once.
Emit it when any of:
- A **required artifact exists but cannot be assessed** — empty, unreadable, or
still entirely `[TO BE CONFIGURED]` / template placeholders. Present-but-empty
is the case that most looks like present.
- A **quality check's input carries no measured data**. Section 3 compares the
performance budgets against "profiling data in `tests/performance/` or recent
`/perf-profile` output" — and `/perf-profile`'s report template pre-fills
`[16.67ms]` as the budget, so it can render ">99% headroom" from zero profiler
data. Placeholder numbers are not measurements: a budget nobody set is not a
budget that was met. Absent data already prompts (Section 4 offers to run
`/perf-profile`); this covers data that is *present and hollow*, which is the
case that looks like a measurement.
- A **test check the tier requires could not be executed** — no test runner is
configured, or the runner is configured but failed to start. Section 3 runs the
suite "if a test runner is configured", and an unconfigured runner produced no
failures, so the test check contributed nothing to the verdict and the gate
could still reach PASS. Meanwhile `testing.strict.logic` and
`.integration` both default to `true`, so the project's own configuration
called those gates BLOCKING. A blocking gate that never ran is the unknown this
verdict exists to name. Remediation is already listed under Common Gaps
(`/test-setup`); this is what the verdict does with it.
> **Scope this to tiers that require tests.** At `qa.level: minimal` no test
> gates apply at all (see the config block above), so a missing runner there is
> the configured posture, not a hole — firing the trigger would make every
> `minimal` gate permanently NOT ASSESSED and stop stage advancement, the same
> over-broad reading the director trigger below warns against. Fires only where
> the resolved tier actually asked for the test check.
- A **`MANUAL CHECK NEEDED` item the user never resolved**. Section 4 already
refuses to assume PASS for unverifiable items and marks them this way — but
until now the verdict vocabulary had nowhere to put one, so an unresolved
manual check had to land inside PASS, CONCERNS or FAIL anyway. This is where it
goes.
- A director the **resolved tier was supposed to spawn** did not return — it
errored, produced no verdict, or was interrupted.
> **Scope this narrowly, and do not read it as "fewer than four directors ran".**
> Section 4b narrows the panel *by design* — 1 director at `minimal`, 2 at
> `standard`, 4 at `full`, and none in `solo` — and that narrowing is a
> deliberate, announced reduction, not a failure to assess. The broad reading
> makes every `minimal`, `standard` and `solo` gate permanently NOT ASSESSED,
> which means the verdict can never be PASS and Section 6 can never advance
> `project.stage`. **That would break stage advancement for most projects,**
> since those are the common tiers. The trigger fires only when a director the
> tier *did* call for fails to come back — a hole in the panel you expected,
> never the panel you deliberately chose.
- A referenced upstream verdict is itself `NOT ASSESSED` — it propagates upward
rather than resolving to a pass.
Never resolve an unknown by assuming the permissive reading. If the check could
not run, that fact is the finding.
---
## 5a. Chain-of-Verification
After drafting the verdict in Phase 5, challenge it before finalising.
**Step 1 — Generate 5 challenge questions** designed to disprove the verdict:
> **Tool-action requirement**: At least 2 of the 5 challenge questions below must be answered by re-reading a specific file (Read tool) or re-running a specific check (Grep tool) — not by reflection alone. Mark these with [TOOL ACTION] to indicate a tool was used.
For a **PASS** draft:
- "Which quality checks did I verify by actually reading a file, vs. inferring they passed?"
- "Are there MANUAL CHECK NEEDED items I marked PASS without user confirmation? [TOOL ACTION] Re-scan the checklist for any [?] or MANUAL CHECK items."
- "Did I confirm all listed artifacts have real content, not just empty headers? [TOOL ACTION] Re-read the file and check it has non-placeholder content."
- "Could any blocker I dismissed as minor actually prevent the phase from succeeding?"
- "Which single check am I least confident in, and why?"
For a **CONCERNS** draft:
- "Could any listed CONCERN be elevated to a blocker given the project's current state?"
- "Is the concern resolvable within the next phase, or does it compound over time?"
- "Did I soften any FAIL condition into a CONCERN to avoid a harder verdict?"
- "Are there artifacts I didn't check that could reveal additional blockers?"
- "Do all the CONCERNS together create a blocking problem even if each is minor alone?"
For a **FAIL** draft:
- "Have I accurately separated hard blockers from strong recommendations?"
- "Are there any PASS items I was too lenient about?"
- "Am I missing any additional blockers the user should know about?"
- "Can I provide a minimal path to PASS — the specific 3 things that must change?"
- "Is the fail condition resolvable, or does it indicate a deeper design problem?"
**Step 2 — Answer each question** independently.
Do NOT reference the draft verdict text — re-check specific files or ask the user.
**Step 3 — Revise if needed:**
- If any answer reveals a missed blocker → upgrade verdict (PASS→CONCERNS or CONCERNS→FAIL)
- If any answer reveals a check that **could not be run** rather than one that
ran and passed → PASS→NOT ASSESSED. The first two PASS-draft questions above
("verified by actually reading a file, vs. inferring", "MANUAL CHECK NEEDED
items I marked PASS") exist to find exactly this, and until now a yes to either
had no verdict to move to
- If any answer reveals an over-stated blocker → downgrade only if citing specific evidence
- Never revise NOT ASSESSED down to PASS by re-reasoning about the missing input.
Only obtaining the input clears it
- If answers are consistent → confirm verdict unchanged
**Step 4 — Note the verification** in the final report output:
`Chain-of-Verification: [N] questions checked — verdict [unchanged | revised from X to Y]`
---
**Read `references/5-verdict.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 6. Update Stage on PASS
When the verdict is **PASS** and the user confirms they want to advance, write the
new stage to BOTH `project.yaml` and the legacy `production/stage.txt`.
**On CONCERNS, the user may override — explicitly.** Do not offer the stage
write by default. If the user asks to advance anyway, list every concern and
ask: "The gate returned CONCERNS. Accept these risks — [list] — and may I update
`project.stage` in `project.yaml` to '[stage]' (and the legacy
`production/stage.txt`)?" Only on an explicit yes, add the `### Accepted Risks`
section to the gate report (each concern, accepted by the user, with the date)
and write the stage as below. **A FAIL is never overridden into a stage change, and
neither is NOT ASSESSED** — the blockers must be fixed, or the missing input
produced, and the gate re-run.
### 6.1 Primary write — `project.yaml`
Set `project.stage` to the new stage name in `project.yaml` at the repo root.
- **If a `project:` block already exists**: Read `project.yaml` first (the Edit
tool requires the file to have been read in this session), then use the Edit
tool to change its `stage:` value.
- **If `project.yaml` exists but has no `project:` block**: Read `project.yaml`
first, then use the Edit tool to insert the block immediately after the
`framework:` block (before `modes:`). Insert exactly (replace `<new-stage>`):
```yaml
project:
stage: <new-stage>
```
- **If `project.yaml` does not exist at all**: create it with the Write tool using
this v1.1 minimal template (replace `<new-stage>` and the date):
```yaml
# CCGS project configuration — single source of truth for project settings.
# Schema: grep the `## <key>` section of .claude/docs/effects-map.md —
# it is ~31k tokens whole, ~900 per section. Do not open it entire.
schema_version: 1
framework:
version: 1.1.2
last_upgraded: <YYYY-MM-DD>
project:
stage: <new-stage>
```
Do not seed `modes.review_mode` here. It is a rigor-fronted knob — `modes.rigor`
supplies its value, so an explicit value would shadow the rigor expansion and pin
the review mode regardless of the project's rigor.
### 6.2 Legacy fallback write — `production/stage.txt`
Also write the single-line stage name (no trailing newline) so hooks that have not
migrated still work. Ensure the `production/` directory exists first:
```bash
mkdir -p production && printf '%s' "Production" > production/stage.txt
```
### 6.3 Verify both writes
After both writes, Read `project.yaml` and `production/stage.txt` and confirm both
show the new stage. If they diverge, report the discrepancy to the user and stop —
a split stage indicator corrupts future auto-detection.
**Always ask before writing**: "Gate passed. May I update `project.stage` in `project.yaml` to 'Production' (and the legacy `production/stage.txt`)?" — on an accepted CONCERNS override, the explicit yes above is that ask.
### 6.4 Rigor-fit check (advisory — never affects the verdict)
After the stage advance is confirmed, apply the raise trigger in
`.claude/docs/settings-guidance.md § 4`: if the new stage is **Production** (or
later) while the resolved `modes.workflow` is `minimal` (the `rigor: minimal`
posture, from the config block above), add one line:
> "You're entering [stage] on `rigor: minimal` — most projects this size run
> `standard`. Revisit with `/settings modes.rigor=standard`?"
Offer it **once**, here at the gate. Route to `/settings` — never change the
setting yourself.
---
**Read `references/6-update-stage.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## 7. Closing Next-Step Widget
After the verdict is presented and any stage update is complete (project.yaml + stage.txt), close with a structured next-step prompt using `AskUserQuestion`.
**Tailor the options to the gate that just ran.** The argument names the phase
being entered, so `/gate-check systems-design` is the Concept → Systems Design gate.
**At `workflow: minimal`, skip the menus below.** They walk the phase ladder, and
the minimal route is not the ladder: offer the first incomplete step of
`paths.minimal` instead (the `--path minimal` rows from Section 3):
`/setup-engine`, then `/brainstorm`, then `/create-stories`, then `/dev-story`
on the next story — the route `/help` gives.
For **Concept → Systems Design** (`/gate-check systems-design`) PASS — option [A] is
`/map-systems` when `design/gdd/systems-index.md` does not exist yet (many
projects write it during Concept, as the workflow catalog orders it), otherwise
`/design-system [first system in the index's design order]`:
```
Gate passed. What would you like to do next?
[A] Run /map-systems — decompose the concept into systems and a design order (recommended next step)
— or, when the systems index already exists: Run /design-system [first system] — author its GDD
[B] Revisit the concept first — return here when it is settled
[C] Stop here for this session
```
For **Systems Design → Technical Setup** (`/gate-check technical-setup`) PASS:
```
Gate passed. What would you like to do next?
[A] Run /create-architecture — produce your master architecture blueprint and ADR work plan (recommended next step)
[B] Design more GDDs first — return here when all MVP systems are complete
[C] Stop here for this session
```
> **Note for the Systems Design → Technical Setup PASS**: `/create-architecture` is the required next step before writing any ADRs. It produces the master architecture document and a prioritized list of ADRs to write. Running `/architecture-decision` without this step means writing ADRs without a blueprint — skip it at your own risk.
For **Technical Setup → Pre-Production** (`/gate-check pre-production`) PASS:
```
Gate passed. What would you like to do next?
[A] Run /create-control-manifest — generate the layer rules manifest from your Accepted ADRs (first, if docs/architecture/control-manifest.md does not exist yet)
[B] Run /vertical-slice — build the Vertical Slice (do this before writing epics — validate fun first)
[C] Write more ADRs first — run /architecture-decision [next-system]
[D] Stop here for this session
```
> **Note for the Technical Setup → Pre-Production PASS**: The Pre-Production sequence is deliberately ordered
> to validate fun before committing to detailed planning:
>
> 1. `/create-control-manifest` — extract technical rules from Accepted ADRs, if not done yet (`/create-epics` requires it at `full`)
> 2. `/vertical-slice` — build the Vertical Slice **FIRST**, before writing epics or stories
> 3. Playtest → `/playtest-report` — at least 1 documented session, 3+ better before committing the full team. `/gate-check production` treats the slice as recommended: skipped → CONCERNS, unplayed → NOT ASSESSED
> 4. `/ux-design [screen]` — UX specs for main menu, core HUD, pause menu (if not done)
> 5. `/create-epics layer:foundation` then `/create-epics layer:core` — plan after fun is validated
> 6. `/create-stories [epic-slug]` for each epic
> 7. `/sprint-plan new`
>
> **Why prototype before epics?** If the prototype reveals the core loop needs to change,
> epics written before that discovery will be partially wrong. Validate fun cheaply first,
> then plan in detail. This is the #1 lesson from GDC postmortem data.
For all other gates, offer the two most logical next steps for that phase plus "Stop here".
---
## 8. Follow-Up Actions
Based on the verdict, suggest specific next steps:
- **No art bible?** → `/art-bible` to create the visual identity specification
- **Art bible exists but no asset specs?** → `/asset-spec system:[name]` to generate per-asset visual specs and generation prompts from approved GDDs
- **No game concept?** → `/brainstorm` to create one
- **No systems index?** → `/map-systems` to decompose the concept into systems
- **Missing design docs?** → `/reverse-document` or delegate to `game-designer`
- **Small design change needed?** → `/quick-design` for changes under about one week of implementation (bypasses full GDD pipeline)
- **No UX specs?** → `/ux-design [screen name]` to author specs, or `/team-ui [feature]` for full pipeline
- **UX specs not reviewed?** → `/ux-review [file]` or `/ux-review all` to validate
- **No accessibility requirements doc?** → run `/ux-design` which creates both `design/accessibility-requirements.md` and `design/ux/interaction-patterns.md` in one step
- **No interaction pattern library?** → `/ux-design patterns` to initialize it
- **Concept or a GDD not reviewed?** → `/design-review [doc]`
- **GDDs not cross-reviewed?** → `/review-all-gdds` (run after all MVP GDDs are individually approved)
- **Cross-GDD consistency issues?** → fix flagged GDDs, then re-run `/review-all-gdds`
- **No test framework?** → `/test-setup` to scaffold the framework for your engine
- **No QA plan for current sprint?** → `/qa-plan sprint` to generate one before implementation begins
- **Missing ADRs?** → `/architecture-decision` for individual decisions
- **No master architecture doc?** → `/create-architecture` for the full blueprint
- **ADRs missing engine compatibility sections?** → Re-run `/architecture-decision`
or manually add Engine Compatibility sections to existing ADRs
- **Missing control manifest?** → `/create-control-manifest` (requires Accepted ADRs)
- **Missing epics?** → `/create-epics layer: foundation` then `/create-epics layer: core` (requires control manifest)
- **Missing stories for an epic?** → `/create-stories [epic-slug]` (run after each epic is created)
- **Stories not implementation-ready?** → `/story-readiness` to validate stories before developers pick them up
- **Tests failing?** → delegate to `lead-programmer` or `qa-tester`
- **No playtest data?** → `/playtest-report`
- **No playtest sessions beyond the minimum?** → Additional sessions give more reliable signal. 3+ total is recommended before committing the full team. Use `/playtest-report` to structure findings.
- **No Difficulty Curve doc?** → Author `design/difficulty-curve.md` by hand from the template at `.claude/docs/templates/difficulty-curve.md`. (`/quick-design` is a related session but writes to `design/quick-specs/`, not to this path — use it to think the curve through, then copy the outcome here.)
- **No player journey map?** → Author `design/player-journey.md` by hand from the template at `.claude/docs/templates/player-journey.md`.
> **Neither of these has a skill that writes it — the remediations must not imply
> otherwise.** Naming "`/ux-design` Phase 2b" would point at the step that *reads*
> `design/player-journey.md`, landing the user back at the check that just
> failed. Naming `/quick-design` would point at a skill that writes
> `design/quick-specs/[name]-[date].md` and would leave this gate still failing.
> Both docs are hand-authored from their templates; say so plainly rather than
> naming a skill that cannot produce them.
- **Need a quick sprint check?** → `/sprint-status` for current sprint progress snapshot
- **Performance unknown?** → `/perf-profile`
- **Not localized?** → `/localize`
- **No security audit, or open CRITICAL/HIGH findings?** → `/security-audit` (after fixes, `/security-audit quick` to confirm)
- **Ready for release?** → `/launch-checklist`
---
**Read `references/7-next-steps.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Collaborative Protocol
@@ -0,0 +1,129 @@
# /gate-check — Section 2b: Workflow Tier Adjustment
> Part of `/gate-check`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 2b. Workflow Tier Adjustment
**In this file:**
- How to apply a gate file's tier reductions
- `qa.level` and the test items; the smoke check is the floor
- A gate with no required artifacts left is NOT ASSESSED, with one exception
- `performance.enforce`
- Per-system overrides (`workflow_overrides.system_overrides`), and the additive overrides
Each gate file carries its own tier reductions (see Section 2). Two rules apply
across all of them:
> **How to apply:** run the loaded gate's checklist, then apply that file's tier
> reduction for the tier resolved in Section 1. **drop** = not checked at this
> tier; **→ recommended** = absent surfaces as CONCERNS, never a Blocker; items
> not named keep their baseline status. Reductions only ever *relax* a
> requirement — the only thing that adds one is `workflow_overrides` (below).
>
> **`qa.level` (Section 1) further relaxes the test items independently of the
> tier:** at `qa.level: minimal` the test-evidence / unit-test items become
> non-required at every workflow tier (so even `workflow: full` does not require
> them); the Section 3 `testing.strict` check is then a no-op.
>
> **It relaxes tests, not the look.** A UI story's retained screenshots, and a
> Visual/Feel story's screenshots plus lead sign-off, are required at every
> `qa.level` wherever the gate file asks for story evidence
> (`.claude/docs/coding-standards.md`: tests are waived at `minimal`, the look
> is not).
>
> **The smoke check is excluded from that relaxation, and is the floor.**
> `qa.level` relaxes *per-story test evidence*; a smoke check is **build health**,
> not story evidence, and the two are already held apart on exactly this basis in
> `.claude/docs/coding-standards.md` ("`/smoke-check` is a build-health gate, not
> a per-story evidence gate ... This divergence is intentional"). So a gate file
> that requires a smoke report keeps requiring it at every `qa.level`.
>
> Without that exclusion the Production → Polish gate had **zero required
> artifacts at `rigor: minimal`** and could not fail on artifacts by
> construction: `minimal` reduced the gate to the smoke check alone, `qa.level`
> then dropped the smoke check too, and one `modes.rigor` setting fires both.
> **A gate with no required artifacts left must say so, and may not return
> PASS.** After applying the tier reduction and the `qa.level` relaxation, count
> what remains required. If the count is zero, report
> **NOT ASSESSED** naming both reducers and the gate — *"Production → Polish at
> `workflow: minimal` + `qa.level: minimal` leaves no required artifact; this
> gate verified nothing"* — rather than a PASS earned by having nothing to check.
> Per `.claude/rules/skill-authoring.md` obligation 1, a run that could not
> assess its scope has not established that the scope is good, and obligation 3
> requires the emptiness to be visible in the output rather than inferable from
> a silent green.
>
> **The one exception: a gate its tier reference file marks "not applicable" at
> this tier** (Systems Design → Technical Setup at `workflow: minimal`). That is
> not a gate with nothing left to check but a transition the tier does not have:
> it PASSes with that file's note, printed in the report. The director panel
> does not run for it — note "Director Panel skipped — gate not applicable at
> `workflow: [tier]`" — and the Section 6 stage write still asks first.
>
> **`performance.enforce` is likewise independent of the tier, and a tier
> reduction never suppresses it.** The performance check in Section 3 runs at
> every workflow tier, and `block` makes a breach a Blocker at every workflow
> tier. Do **not** read a gate file's *"everything else drops"* as dropping it:
> `off` is the only thing that makes budgets informational, and it is a
> deliberate choice the user makes on the same key.
>
> Without this, `performance.enforce: block` is **inert on every `rigor: minimal`
> project** — the Polish gate's `minimal` reduction drops everything outside its
> floor, and "Performance is within budget" sits in the dropped remainder. A
> setting that works only when a rule is disregarded is not wired.
### Per-system overrides (`workflow_overrides.system_overrides`)
Independent of the project-level tier above, and applied **only** on the gates
that validate MVP GDDs (Systems Design → Technical Setup, and the GDD-completeness
checks at Pre-Production → Production). For each system, resolve its effective
tier:
1. If the block's `system_overrides` lists `<system>` → that tier
2. Else the project-level `workflow`
**Before applying any of them, check the block the other way round: does every
KEY match a system?** `<system>` is the GDD filename stem
(`.claude/docs/workflow-modes.md`), so for each key in `system_overrides`, look
for `design/gdd/<key>.md`. Any key with no matching stem is reported, naming the
key and listing the stems that do exist:
> `system_overrides key 'no-such-system' matches no GDD in design/gdd/. Available stems: combat, inventory, forge-heat-system. This override is doing nothing.`
Surface it as a **CONCERNS**-level finding, not a Blocker — the project is still
gateable, but an override the user believes is in force and is not is exactly how
a documented escape hatch silently stops working.
This is the rule in `.claude/docs/workflow-modes.md`: a key that matches no
system is an error, not a no-op. The story skills resolve only in the system →
override direction, so an orphan key is invisible to them; `/gate-check`, which
resolves the whole block, is where it is caught.
Validate each GDD against its own effective tier's section count:
- A system pinned **higher** than the project (e.g. `system_overrides.combat:
full` on a `standard` project) **blocks the gate** until that system's GDD
meets the higher bar (combat → all 8 sections). This is the one case where a
per-system setting makes the gate *stricter* than the project tier.
- A system pinned **lower** (e.g. `inventory: minimal`) relaxes only that system
— its GDD is checked at the lower tier; every other system stays at the project
level. A system pinned **`minimal` imposes no GDD section requirement at all**
(`minimal` = "game brief replaces GDDs" — `.claude/docs/workflow-modes.md`): it
never blocks the gate on a missing or incomplete GDD. Do not invent an
"acceptance-criteria-only" floor for it — there is none.
> **Additive overrides (the only things that make the gate stricter).**
> - `workflow_overrides.art_bible_strict: true` forces the complete (9-section)
> art bible at the Technical Setup → Pre-Production and Pre-Production →
> Production gates regardless of tier or whether visual-asset stories exist.
> - `workflow_overrides.edge_cases: true` and `workflow_overrides.tuning_knobs:
> true` force those GDD sections required when validating GDD completeness,
> additive on top of the resolved tier (e.g. at `standard`, `tuning_knobs: true`
> makes the otherwise-optional Tuning Knobs section blocking). These never
> relax — a `false` value is the default/no-op, never a way to drop a section
> the tier already requires.
---
@@ -0,0 +1,165 @@
# /gate-check — Section 3: Run the Gate Check
> Part of `/gate-check`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 3. Run the Gate Check
**In this file:**
- Artifact Checks
- Quality Checks
- Cross-Reference Checks
**Before running artifact checks**, read `docs/consistency-failures.md` if it exists.
Extract entries whose Domain matches the target phase (e.g., if checking
Systems Design → Technical Setup, pull entries in Economy, Combat, or any GDD domain;
if checking Technical Setup → Pre-Production, pull entries in Architecture, Engine).
Carry these as context — recurring conflict patterns in the target domain warrant
increased scrutiny on those specific checks.
For each item in the target gate:
### Artifact Checks
**Resolve existence and counts deterministically — do not open files to find out
what exists:**
```
Bash: bash .claude/scripts/artifact-check.sh --phase [source-phase]
```
Pass the phase being advanced *from* (its steps are the work that must be
complete): `systems-design` for the Systems Design → Technical Setup gate,
`pre-production` for Pre-Production → Production, and so on.
At `workflow: minimal`, also run
`bash .claude/scripts/artifact-check.sh --path minimal`: the brief and stories
live on that path, not on any phase, and its `game-brief` and `create-stories`
rows are this tier's floor.
It reads `workflow-catalog.yaml` — which already encodes each step's `glob`,
`pattern`, `min_count` and `any_of` — and reports per step:
| status | Meaning |
|---|---|
| `PRESENT` | glob matched, `min_count` met, `pattern` found where specified |
| `ABSENT` | nothing matched |
| `SHORT` | matched but fewer than `min_count` (`count=` and `min=` given) |
| `PATTERN_MISS` | files exist but none contains the required marker |
| `NO_CHECK` | the step declares no artifact — **not detectable from disk** |
It emits observations, never a verdict: **you** apply the workflow tier and the
required/optional split from Section 2. An `ABSENT` required artifact is a
blocker at `full` and frequently not one at `minimal`; the script does not know
that and does not decide it.
**`NO_CHECK` is not `PRESENT`.** The header prints a `NO_CHECK:` count before any
row precisely so this cannot be skimmed past. Those steps were *scanned*, not
*satisfied* — carry each into Section 4 (Collaborative Assessment) and ask, or
mark MANUAL CHECK NEEDED. A gate that reports PASS because most of its checklist
was undetectable is the failure mode this count exists to prevent.
**Existence is not adequacy.** The script cannot tell a real document from a
template skeleton. So: for any artifact the verdict actually turns on, spot-read
it and confirm it has real content — the same escalation rule the
`gdd-structure-check.sh` step below uses. Do not spot-read artifacts the verdict
does not turn on.
> **A smoke report is always an artifact the verdict turns on — spot-reading it
> is mandatory, not discretionary.** At `minimal` it is frequently the *only*
> required artifact, so the whole gate rests on one file that nothing generated
> and nothing verifies. Check its claims against the repo, and raise any that the
> tree contradicts:
>
> - It reports a passing automated suite → the engine's test root must actually
> contain test files and the project must have a runner. "24 passed, 0 failed"
> in a repo with no test files under that root — `tests/unit/` and
> `tests/integration/` on Godot, `Assets/Tests/` on Unity,
> `Source/<Module>/Private/Tests/` on Unreal — and no runner is a finding, not
> evidence.
> - It marks a critical path PASS → the code for that path must exist in the code
> root. A PASS on "banking ends the run" with no banking code is a finding.
> - It carries no date, or predates the newest commit touching the code root →
> say so; a stale smoke report describes a build that no longer exists.
>
> Report a contradiction at the same level the artifact was required at: a
> Blocker where the smoke check is required, CONCERNS where it is recommended.
> Existence plus a verdict-line grep would clear a fabricated report.
For code checks, verify directory structure and file counts.
**Systems Design → Technical Setup gate — cross-GDD review check**:
Use `Glob('design/gdd/gdd-cross-review-*.md')` to find the `/review-all-gdds` report.
If no file matches: at `full` mark the "cross-GDD review report exists" artifact as
**FAIL** and surface it prominently ("No `/review-all-gdds` report found in
`design/gdd/`. Run `/review-all-gdds` before advancing to Technical Setup."); at
`standard` the report is recommended, so mark it **CONCERNS**, not a blocker; at
`minimal` this gate is not applicable (see the gate file). If a file is found, read it and
check the verdict line: a FAIL verdict means the cross-GDD consistency check failed
and must be resolved before advancing. A NOT ASSESSED verdict means that review
could not compare the GDDs, so it satisfies nothing here: mark the item NOT
ASSESSED for this gate, never passed.
### Quality Checks
- For test checks: Run the test suite via `Bash` if a test runner is configured.
**If no runner is configured, that is `NOT ASSESSED`, not a silent skip** — see
the trigger in the verdict section. A gate that ran no tests found no test
failures, which is not the same as passing.
A test failure's effect on the verdict depends on the `testing.strict` block
**resolved in Phase 1** (`resolve_config` merges `project.local.yaml` over
`project.yaml`; reading the file directly would drop a local override), per
test type:
- **Logic** — unit-level failures (`tests/unit/` on Godot, Edit Mode on
Unity), gated by `testing.strict.logic`.
- **Integration** — failures in `tests/integration/` on Godot, Play Mode on
Unity, gated by `testing.strict.integration`. On Unreal, where one root
(`Source/<Module>/Private/Tests/`) holds both, classify a failure by its
story's Type, or apply the stricter of the two levels when that is unknown.
- For each type: take `testing.strict.<type>` from that block; use it only
if its value is `true` or `false` (case-insensitive). If the key is absent,
empty, or holds any other value, read `testing.strict` as a plain boolean
(legacy single-value form); if that too is absent or invalid, default to
`true` (Logic and Integration are both strict by default — behavior unchanged
from before this setting existed). Surface any unrecognized value to the user.
- At a strict (`true`) gate level, failures of that type are **Blockers**
(verdict FAIL). At an advisory (`false`) level, they are **Concerns**
(verdict minimum CONCERNS, not FAIL) — list them under Recommendations, not
Blockers.
- For design review checks, gather section presence **deterministically** — do not
read the GDDs to count headings:
```
Bash: bash .claude/scripts/gdd-structure-check.sh
```
It prints a `PRESENT:` / `ABSENT:` pair per GDD and already accepts
`## Detailed Design` as satisfying the `Detailed Rules` requirement. It reports
presence only and makes no REQUIRED/ADVISORY judgment.
Then apply each GDD's **effective tier** (per-system resolution below) to those
lists — all 8 sections at `full`, the 5 standard sections (+ conditional
Formulas) at `standard`. A missing *required* section blocks; a missing section
that is optional at the effective tier is advisory. A section reported PRESENT
can still fail review if it is an empty heading — spot-read any section the
verdict actually turns on.
- For performance checks: read the budgets (`performance.target_framerate`,
`frame_budget_ms`, `draw_call_limit`, `memory_ceiling_mb`) from `project.yaml`
(else technical-preferences.md) and compare against any profiling data in
`tests/performance/` or recent `/perf-profile` output. What a breach *means*
is set by `performance.enforce`, taken from the Phase 1 resolved block (it is
locally overridable, so do not read the file for this one):
- `warn` (default) — breaches are **CONCERNS**, never Blockers.
- `block` — breaches are **Blockers** from the Polish gate onward.
- `off` — budgets are informational; do not surface breaches in the verdict.
Only these three values are recognized. Surface anything else to the user and
fall back to `warn` rather than guessing.
- For localization checks: `Grep` for hardcoded strings in the **code root** (resolve per `.claude/docs/code-root-resolution.md`). **If the code root is unresolved, report `NOT ASSESSED — code root unresolved` rather than zero hits.**
### Cross-Reference Checks
- Compare `design/gdd/` documents against implementations in the **code root**
- Check that every system referenced in architecture docs has corresponding code
- Verify sprint plans reference real work items
---
@@ -0,0 +1,142 @@
# /gate-check — Sections 4 and 4b: Assessment and Director Panel
> Part of `/gate-check`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 4. Collaborative Assessment
**In this file:**
- 4. Collaborative Assessment: unverifiable items are never PASS
- 4b. Director Panel Assessment: `review_mode` decides whether directors spawn, `workflow` decides the panel width
- Gate IDs
- Naming the omissions, and applying the panel to the verdict
For items that can't be automatically verified, **ask the user**:
- "I can't automatically verify that the core loop plays well. Has it been playtested?"
- "No playtest report found. Has informal testing been done?"
- "Performance profiling data isn't available. Would you like to run `/perf-profile`?"
**Never assume PASS for unverifiable items.** Mark them as MANUAL CHECK NEEDED.
An answer resolves the item: "no" or "not yet" is a checked, failed item
(CONCERNS or FAIL, naming the skill that closes it — `/design-review [doc]` for
an unreviewed concept or GDD) — except a play question at the Production gate
(a human has played the Vertical Slice; at `minimal`, the core loop is fun on
the current build), where "not yet" means nobody has played it: NOT ASSESSED
(`gate-production.md`). Only an unanswered item or "I don't know" stays
MANUAL CHECK NEEDED, which Section 5 turns into NOT ASSESSED.
This applies to questions about the project's state. Declining an offer to
produce missing data (e.g. `/perf-profile`) leaves the item NOT ASSESSED; at
`performance.enforce: off` it stays out of the verdict.
---
## 4b. Director Panel Assessment
The panel is set by **two independent axes**, both resolved in Phase 1: `review_mode`
decides *whether* the panel runs, `workflow` decides *how wide* it is.
**Axis 1 — `review_mode` decides whether any director spawns:**
- `solo` → skip the panel entirely. Note in output: "Director Panel skipped — Solo mode. Gate verdict based on artifact and quality checks only." Proceed to Phase 5.
- `lean` → run the panel (phase gates always run in lean mode — this is their purpose).
- `full` → run the panel.
**Axis 2 — `workflow` decides the panel width.** Directors are Opus-tier, so the
panel is sized to the project rather than fixed at four. The gate still runs at
every tier; only its breadth scales:
| `workflow` | Panel | Directors |
|---|---|---|
| `minimal` | 1 | `producer` |
| `standard` | 2 | `technical-director`, `producer` |
| `full` | 4 | `creative-director`, `technical-director`, `producer`, `art-director` |
`producer` is in every panel — scope and schedule readiness is the one judgment
no tier makes optional. `technical-director` joins at `standard` because that is
the first tier requiring architecture artifacts. `creative-director` and
`art-director` join at `full`, the only tier requiring the full art bible and
UX spec set for them to assess.
> **Width is not the same as strictness.** A narrower panel does not soften the
> verdict: the escalation rule in `.claude/docs/director-gates.md` is unchanged —
> the strictest verdict returned by *whoever ran* still wins. Do not infer PASS
> from a perspective that was never consulted.
Before generating the final verdict, spawn the directors for the resolved tier as **parallel subagents** via `Agent` using the parallel gate protocol from `.claude/docs/director-gates.md`. Issue all the `Agent` calls simultaneously — do not wait for one before starting the next.
**Gate IDs:**
1. **`creative-director`** — gate **CD-PHASE-GATE** (`.claude/docs/director-gates/cd-phase-gate.md`)
2. **`technical-director`** — gate **TD-PHASE-GATE** (`.claude/docs/director-gates/td-phase-gate.md`)
3. **`producer`** — gate **PR-PHASE-GATE** (`.claude/docs/director-gates/pr-phase-gate.md`)
4. **`art-director`** — gate **AD-PHASE-GATE** (`.claude/docs/director-gates/ad-phase-gate.md`)
Pass to each the target phase name, the resolved `workflow` tier, the target
gate's required and recommended artifacts at the resolved tier (the loaded gate
file's checklist after its tier reduction and the `qa.level` relaxation — what
this gate asks for, not what a later one will), the list of artifacts present,
and its gate's own context — named here, so this session never has to read the
gate files:
- **CD-PHASE-GATE**: the game pillars and core fantasy (from
`design/gdd/game-concept.md`, else `design/game-brief.md`).
- **TD-PHASE-GATE**: the architecture document path, the engine reference path
(`docs/engine-reference/<engine>/VERSION.md`), and the ADR list.
- **PR-PHASE-GATE**: the sprint and milestone artifacts present, `team.size` as
resolved above (with the current sprint plan's capacity, if a plan exists), and
the number of stories under `production/epics/` whose status is `Blocked`. At
`workflow: minimal`, pass the Build order in `design/game-brief.md` as the plan — that
tier has no sprint plan.
- **AD-PHASE-GATE**: the art and visual artifacts present, the Visual Identity
Anchor (from `design/gdd/game-concept.md`, else the "Art & audio direction"
line of `design/game-brief.md`), and the art bible path.
Pass each context item as one of three things, so no director has to guess:
- **Present** — its path or value (`0` blocked stories is a value).
- **"none"** — the target gate (or an earlier one) requires or recommends it at
this tier and it does not exist (no architecture document at
`/gate-check pre-production`). For the director that is a fact about the
project to judge, not a missing input.
- **"not expected before [phase]"** — the target gate does not ask for it yet;
name the phase whose gate first does (the architecture document and ADRs
before Pre-Production, the sprint plan before Production). One this tier never
requires is "not required at `workflow: [tier]`" (any sprint plan at
`minimal`). Neither is ever passed as "none", and neither is a finding — a
director judges readiness for the phase being entered, not a later one.
**Name the omissions in the output.** Below the Director Panel summary, when the
panel ran narrower than four, state which perspectives did not run and how to get
them — e.g. "Panel: 2 of 4 (`workflow: standard`). Creative and Art perspectives
not consulted. Raise `modes.rigor` to `full` (or set `modes.workflow: full`) for
the complete panel." Name the setting the config block shows as `workflow`'s
source: when `modes.workflow` is set on its own, raising `modes.rigor` does not
change it. Never point to `--review full` for this — `--review` decides whether
the panel runs, not how wide it is. A silently narrow panel reads as a clean bill
of health from reviewers who never looked.
**Collect every response from the directors that ran, then present the Director Panel summary** (one row per director that ran; name the ones `workflow` left out):
```
## Director Panel Assessment
Creative Director: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
Technical Director: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
Producer: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
Art Director: [READY / CONCERNS / NOT READY / NOT ASSESSED]
[feedback]
```
**Apply to the verdict:**
- Any director returns NOT READY → verdict is minimum FAIL (no override turns a FAIL into a stage change — Section 6)
- Any director returns CONCERNS → verdict is minimum CONCERNS
- Any director returns NOT ASSESSED (and none returned NOT READY or CONCERNS) → verdict at best NOT ASSESSED; name the input that director said was missing — it never counts as READY
- Every director that ran returns READY → eligible for PASS (still subject to artifact and quality checks from Section 3)
---
@@ -0,0 +1,167 @@
# /gate-check — Sections 5 and 5a: Verdict and Chain-of-Verification
> Part of `/gate-check`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 5. Output the Verdict
**In this file:**
- 5. Output the Verdict: the report, `NOT ASSESSED`, verdict precedence
- 5a. Chain-of-Verification: Steps 1-4
```
## Gate Check: [Current Phase] → [Target Phase]
**Date**: [date]
**Checked by**: gate-check skill
### Required Artifacts: [X/Y present]
- [x] design/gdd/game-concept.md (design/game-brief.md at `minimal`) — exists, 2.4KB
- [ ] docs/architecture/ — MISSING (no ADRs found)
- [x] production/sprints/ — exists, 1 sprint plan
### Quality Checks: [X/Y passing]
- [x] GDD has 8/8 required sections
- [ ] Tests — FAILED (3 failures in tests/unit/)
- [?] Core loop playtested — MANUAL CHECK NEEDED
### Blockers
1. **No Architecture Decision Records** — Run `/architecture-decision` to create one
covering core system architecture before entering production.
2. **3 test failures** — Fix failing tests in tests/unit/ before advancing.
### Recommendations
- [Priority actions to resolve blockers]
- [Optional improvements that aren't blocking]
### Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
- **PASS**: All required artifacts present, all quality checks passing
- **CONCERNS**: Minor gaps exist but can be addressed during the next phase —
the stage advances only if the user explicitly accepts them (Section 6)
- **FAIL**: Critical blockers must be resolved before advancing
- **NOT ASSESSED**: One or more required checks could not be run at all — name
which, and why, in the Blockers section
### Accepted Risks (only when the user advanced on CONCERNS)
- [each concern, as listed above] — accepted by the user, [date]
```
**`NOT ASSESSED` — when the gate could not look.** Rank: it **outranks PASS**
(a gate that could not check part of its scope has not established the phase is
ready) and **ranks below CONCERNS and FAIL** (a known blocker is more actionable
than an unknown, and demoting it behind an access problem buries it). It is not a
softer FAIL: "I checked and found a blocker" and "I could not check" need
different fixes — one needs work done, the other needs the input produced or made
readable.
**Verdict precedence — first matching rule wins**, evaluated in this order:
**FAIL**, then **CONCERNS**, then **NOT ASSESSED**, then **PASS**. A gate with
both a real blocker and an unassessable check is FAIL: the blocker is the
actionable finding. Stating the order mechanically removes the inference — the
rank sentence above says what outranks what, but only an ordered list says what
to do when two conditions hold at once.
Emit it when any of:
- A **required artifact exists but cannot be assessed** — empty, unreadable, or
still entirely `[TO BE CONFIGURED]` / template placeholders. Present-but-empty
is the case that most looks like present.
- A **quality check's input carries no measured data**. Section 3 compares the
performance budgets against "profiling data in `tests/performance/` or recent
`/perf-profile` output" — and `/perf-profile`'s report template pre-fills
`[16.67ms]` as the budget, so it can render ">99% headroom" from zero profiler
data. Placeholder numbers are not measurements: a budget nobody set is not a
budget that was met. Absent data already prompts (Section 4 offers to run
`/perf-profile`); this covers data that is *present and hollow*, which is the
case that looks like a measurement.
- A **test check the tier requires could not be executed** — no test runner is
configured, or the runner is configured but failed to start. Section 3 runs the
suite "if a test runner is configured", and an unconfigured runner produced no
failures, so the test check contributed nothing to the verdict and the gate
could still reach PASS. Meanwhile `testing.strict.logic` and
`.integration` both default to `true`, so the project's own configuration
called those gates BLOCKING. A blocking gate that never ran is the unknown this
verdict exists to name. Remediation is already listed under Common Gaps
(`/test-setup`); this is what the verdict does with it.
> **Scope this to tiers that require tests.** At `qa.level: minimal` no test
> gates apply at all (see the config block above), so a missing runner there is
> the configured posture, not a hole — firing the trigger would make every
> `minimal` gate permanently NOT ASSESSED and stop stage advancement, the same
> over-broad reading the director trigger below warns against. Fires only where
> the resolved tier actually asked for the test check.
- A **`MANUAL CHECK NEEDED` item the user never resolved**. Section 4 already
refuses to assume PASS for unverifiable items and marks them this way — but
until now the verdict vocabulary had nowhere to put one, so an unresolved
manual check had to land inside PASS, CONCERNS or FAIL anyway. This is where it
goes.
- A director the **resolved tier was supposed to spawn** did not return — it
errored, produced no verdict, or was interrupted.
> **Scope this narrowly, and do not read it as "fewer than four directors ran".**
> Section 4b narrows the panel *by design* — 1 director at `minimal`, 2 at
> `standard`, 4 at `full`, and none in `solo` — and that narrowing is a
> deliberate, announced reduction, not a failure to assess. The broad reading
> makes every `minimal`, `standard` and `solo` gate permanently NOT ASSESSED,
> which means the verdict can never be PASS and Section 6 can never advance
> `project.stage`. **That would break stage advancement for most projects,**
> since those are the common tiers. The trigger fires only when a director the
> tier *did* call for fails to come back — a hole in the panel you expected,
> never the panel you deliberately chose.
- A referenced upstream verdict is itself `NOT ASSESSED` — it propagates upward
rather than resolving to a pass.
Never resolve an unknown by assuming the permissive reading. If the check could
not run, that fact is the finding.
---
## 5a. Chain-of-Verification
After drafting the verdict in Phase 5, challenge it before finalising.
**Step 1 — Generate 5 challenge questions** designed to disprove the verdict:
> **Tool-action requirement**: At least 2 of the 5 challenge questions below must be answered by re-reading a specific file (Read tool) or re-running a specific check (Grep tool) — not by reflection alone. Mark these with [TOOL ACTION] to indicate a tool was used.
For a **PASS** draft:
- "Which quality checks did I verify by actually reading a file, vs. inferring they passed?"
- "Are there MANUAL CHECK NEEDED items I marked PASS without user confirmation? [TOOL ACTION] Re-scan the checklist for any [?] or MANUAL CHECK items."
- "Did I confirm all listed artifacts have real content, not just empty headers? [TOOL ACTION] Re-read the file and check it has non-placeholder content."
- "Could any blocker I dismissed as minor actually prevent the phase from succeeding?"
- "Which single check am I least confident in, and why?"
For a **CONCERNS** draft:
- "Could any listed CONCERN be elevated to a blocker given the project's current state?"
- "Is the concern resolvable within the next phase, or does it compound over time?"
- "Did I soften any FAIL condition into a CONCERN to avoid a harder verdict?"
- "Are there artifacts I didn't check that could reveal additional blockers?"
- "Do all the CONCERNS together create a blocking problem even if each is minor alone?"
For a **FAIL** draft:
- "Have I accurately separated hard blockers from strong recommendations?"
- "Are there any PASS items I was too lenient about?"
- "Am I missing any additional blockers the user should know about?"
- "Can I provide a minimal path to PASS — the specific 3 things that must change?"
- "Is the fail condition resolvable, or does it indicate a deeper design problem?"
**Step 2 — Answer each question** independently.
Do NOT reference the draft verdict text — re-check specific files or ask the user.
**Step 3 — Revise if needed:**
- If any answer reveals a missed blocker → upgrade verdict (PASS→CONCERNS or CONCERNS→FAIL)
- If any answer reveals a check that **could not be run** rather than one that
ran and passed → PASS→NOT ASSESSED. The first two PASS-draft questions above
("verified by actually reading a file, vs. inferring", "MANUAL CHECK NEEDED
items I marked PASS") exist to find exactly this, and until now a yes to either
had no verdict to move to
- If any answer reveals an over-stated blocker → downgrade only if citing specific evidence
- Never revise NOT ASSESSED down to PASS by re-reasoning about the missing input.
Only obtaining the input clears it
- If answers are consistent → confirm verdict unchanged
**Step 4 — Note the verification** in the final report output:
`Chain-of-Verification: [N] questions checked — verdict [unchanged | revised from X to Y]`
---
@@ -0,0 +1,84 @@
# /gate-check — Section 6: Update Stage on PASS
> Part of `/gate-check`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 6. Update Stage on PASS
When the verdict is **PASS** and the user confirms they want to advance, write the
new stage to BOTH `project.yaml` and the legacy `production/stage.txt`.
**On CONCERNS, the user may override — explicitly.** Do not offer the stage
write by default. If the user asks to advance anyway, list every concern and
ask: "The gate returned CONCERNS. Accept these risks — [list] — and may I update
`project.stage` in `project.yaml` to '[stage]' (and the legacy
`production/stage.txt`)?" Only on an explicit yes, add the `### Accepted Risks`
section to the gate report (each concern, accepted by the user, with the date)
and write the stage as below. **A FAIL is never overridden into a stage change, and
neither is NOT ASSESSED** — the blockers must be fixed, or the missing input
produced, and the gate re-run.
### 6.1 Primary write — `project.yaml`
Set `project.stage` to the new stage name in `project.yaml` at the repo root.
- **If a `project:` block already exists**: Read `project.yaml` first (the Edit
tool requires the file to have been read in this session), then use the Edit
tool to change its `stage:` value.
- **If `project.yaml` exists but has no `project:` block**: Read `project.yaml`
first, then use the Edit tool to insert the block immediately after the
`framework:` block (before `modes:`). Insert exactly (replace `<new-stage>`):
```yaml
project:
stage: <new-stage>
```
- **If `project.yaml` does not exist at all**: create it with the Write tool using
this v1.1 minimal template (replace `<new-stage>` and the date):
```yaml
# CCGS project configuration — single source of truth for project settings.
# Schema: grep the `## <key>` section of .claude/docs/effects-map.md —
# it is ~31k tokens whole, ~900 per section. Do not open it entire.
schema_version: 1
framework:
version: 1.1.3
last_upgraded: <YYYY-MM-DD>
project:
stage: <new-stage>
```
Do not seed `modes.review_mode` here. It is a rigor-fronted knob — `modes.rigor`
supplies its value, so an explicit value would shadow the rigor expansion and pin
the review mode regardless of the project's rigor.
### 6.2 Legacy fallback write — `production/stage.txt`
Also write the single-line stage name (no trailing newline) so hooks that have not
migrated still work. Ensure the `production/` directory exists first:
```bash
mkdir -p production && printf '%s' "Production" > production/stage.txt
```
### 6.3 Verify both writes
After both writes, Read `project.yaml` and `production/stage.txt` and confirm both
show the new stage. If they diverge, report the discrepancy to the user and stop —
a split stage indicator corrupts future auto-detection.
**Always ask before writing**: "Gate passed. May I update `project.stage` in `project.yaml` to 'Production' (and the legacy `production/stage.txt`)?" — on an accepted CONCERNS override, the explicit yes above is that ask.
### 6.4 Rigor-fit check (advisory — never affects the verdict)
After the stage advance is confirmed, apply the raise trigger in
`.claude/docs/settings-guidance.md § 4`: if the new stage is **Production** (or
later) while the resolved `modes.workflow` is `minimal` (the `rigor: minimal`
posture, from the config block above), add one line:
> "You're entering [stage] on `rigor: minimal` — most projects this size run
> `standard`. Revisit with `/settings modes.rigor=standard`?"
Offer it **once**, here at the gate. Route to `/settings` — never change the
setting yourself.
---
@@ -0,0 +1,120 @@
# /gate-check — Sections 7 and 8: Next Step and Follow-Up
> Part of `/gate-check`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## 7. Closing Next-Step Widget
**In this file:**
- 7. Closing Next-Step Widget: per gate, and the `workflow: minimal` route
- 8. Follow-Up Actions
After the verdict is presented and any stage update is complete (project.yaml + stage.txt), close with a structured next-step prompt using `AskUserQuestion`.
**Tailor the options to the gate that just ran.** The argument names the phase
being entered, so `/gate-check systems-design` is the Concept → Systems Design gate.
**At `workflow: minimal`, skip the menus below.** They walk the phase ladder, and
the minimal route is not the ladder: offer the first incomplete step of
`paths.minimal` instead (the `--path minimal` rows from Section 3):
`/setup-engine`, then `/brainstorm`, then `/create-stories`, then `/dev-story`
on the next story — the route `/help` gives.
For **Concept → Systems Design** (`/gate-check systems-design`) PASS — option [A] is
`/map-systems` when `design/gdd/systems-index.md` does not exist yet (many
projects write it during Concept, as the workflow catalog orders it), otherwise
`/design-system [first system in the index's design order]`:
```
Gate passed. What would you like to do next?
[A] Run /map-systems — decompose the concept into systems and a design order (recommended next step)
— or, when the systems index already exists: Run /design-system [first system] — author its GDD
[B] Revisit the concept first — return here when it is settled
[C] Stop here for this session
```
For **Systems Design → Technical Setup** (`/gate-check technical-setup`) PASS:
```
Gate passed. What would you like to do next?
[A] Run /create-architecture — produce your master architecture blueprint and ADR work plan (recommended next step)
[B] Design more GDDs first — return here when all MVP systems are complete
[C] Stop here for this session
```
> **Note for the Systems Design → Technical Setup PASS**: `/create-architecture` is the required next step before writing any ADRs. It produces the master architecture document and a prioritized list of ADRs to write. Running `/architecture-decision` without this step means writing ADRs without a blueprint — skip it at your own risk.
For **Technical Setup → Pre-Production** (`/gate-check pre-production`) PASS:
```
Gate passed. What would you like to do next?
[A] Run /create-control-manifest — generate the layer rules manifest from your Accepted ADRs (first, if docs/architecture/control-manifest.md does not exist yet)
[B] Run /vertical-slice — build the Vertical Slice (do this before writing epics — validate fun first)
[C] Write more ADRs first — run /architecture-decision [next-system]
[D] Stop here for this session
```
> **Note for the Technical Setup → Pre-Production PASS**: The Pre-Production sequence is deliberately ordered
> to validate fun before committing to detailed planning:
>
> 1. `/create-control-manifest` — extract technical rules from Accepted ADRs, if not done yet (`/create-epics` requires it at `full`)
> 2. `/vertical-slice` — build the Vertical Slice **FIRST**, before writing epics or stories
> 3. Playtest → `/playtest-report` — at least 1 documented session, 3+ better before committing the full team. `/gate-check production` treats the slice as recommended: skipped → CONCERNS, unplayed → NOT ASSESSED
> 4. `/ux-design [screen]` — UX specs for main menu, core HUD, pause menu (if not done)
> 5. `/create-epics layer:foundation` then `/create-epics layer:core` — plan after fun is validated
> 6. `/create-stories [epic-slug]` for each epic
> 7. `/sprint-plan new`
>
> **Why prototype before epics?** If the prototype reveals the core loop needs to change,
> epics written before that discovery will be partially wrong. Validate fun cheaply first,
> then plan in detail. This is the #1 lesson from GDC postmortem data.
For all other gates, offer the two most logical next steps for that phase plus "Stop here".
---
## 8. Follow-Up Actions
Based on the verdict, suggest specific next steps:
- **No art bible?** → `/art-bible` to create the visual identity specification
- **Art bible exists but no asset specs?** → `/asset-spec system:[name]` to generate per-asset visual specs and generation prompts from approved GDDs
- **No game concept?** → `/brainstorm` to create one
- **No systems index?** → `/map-systems` to decompose the concept into systems
- **Missing design docs?** → `/reverse-document` or delegate to `game-designer`
- **Small design change needed?** → `/quick-design` for changes under about one week of implementation (bypasses full GDD pipeline)
- **No UX specs?** → `/ux-design [screen name]` to author specs, or `/team-ui [feature]` for full pipeline
- **UX specs not reviewed?** → `/ux-review [file]` or `/ux-review all` to validate
- **No accessibility requirements doc?** → run `/ux-design` which creates both `design/accessibility-requirements.md` and `design/ux/interaction-patterns.md` in one step
- **No interaction pattern library?** → `/ux-design patterns` to initialize it
- **Concept or a GDD not reviewed?** → `/design-review [doc]`
- **GDDs not cross-reviewed?** → `/review-all-gdds` (run after all MVP GDDs are individually approved)
- **Cross-GDD consistency issues?** → fix flagged GDDs, then re-run `/review-all-gdds`
- **No test framework?** → `/test-setup` to scaffold the framework for your engine
- **No QA plan for current sprint?** → `/qa-plan sprint` to generate one before implementation begins
- **Missing ADRs?** → `/architecture-decision` for individual decisions
- **No master architecture doc?** → `/create-architecture` for the full blueprint
- **ADRs missing engine compatibility sections?** → Re-run `/architecture-decision`
or manually add Engine Compatibility sections to existing ADRs
- **Missing control manifest?** → `/create-control-manifest` (requires Accepted ADRs)
- **Missing epics?** → `/create-epics layer: foundation` then `/create-epics layer: core` (requires control manifest)
- **Missing stories for an epic?** → `/create-stories [epic-slug]` (run after each epic is created)
- **Stories not implementation-ready?** → `/story-readiness` to validate stories before developers pick them up
- **Tests failing?** → delegate to `lead-programmer` or `qa-tester`
- **No playtest data?** → `/playtest-report`
- **No playtest sessions beyond the minimum?** → Additional sessions give more reliable signal. 3+ total is recommended before committing the full team. Use `/playtest-report` to structure findings.
- **No Difficulty Curve doc?** → Author `design/difficulty-curve.md` by hand from the template at `.claude/docs/templates/difficulty-curve.md`. (`/quick-design` is a related session but writes to `design/quick-specs/`, not to this path — use it to think the curve through, then copy the outcome here.)
- **No player journey map?** → Author `design/player-journey.md` by hand from the template at `.claude/docs/templates/player-journey.md`.
> **Neither of these has a skill that writes it — the remediations must not imply
> otherwise.** Naming "`/ux-design` Phase 2b" would point at the step that *reads*
> `design/player-journey.md`, landing the user back at the check that just
> failed. Naming `/quick-design` would point at a skill that writes
> `design/quick-specs/[name]-[date].md` and would leave this gate still failing.
> Both docs are hand-authored from their templates; say so plainly rather than
> naming a skill that cannot produce them.
- **Need a quick sprint check?** → `/sprint-status` for current sprint progress snapshot
- **Performance unknown?** → `/perf-profile`
- **Not localized?** → `/localize`
- **No security audit, or open CRITICAL/HIGH findings?** → `/security-audit` (after fixes, `/security-audit quick` to confirm)
- **Ready for release?** → `/launch-checklist`
---
+2
View File
@@ -8,6 +8,8 @@ allowed-tools: Read, Glob, Grep, Write, Edit, Bash, Agent, AskUserQuestion
model: sonnet
---
# Hotfix
> **Explicit invocation only**: This skill should only run when the user explicitly requests it with `/hotfix`. Do not auto-invoke based on context matching.
## Phase 1: Assess Severity
+2
View File
@@ -16,6 +16,8 @@ every file write follows `.claude/docs/automation-modes.md`
Resolved above — use as-is. No block → defaults in `.claude/docs/config-resolution.md`.
# Launch Checklist
**Scope this checklist to the project.** Emitting every item for every platform
trains the reader to skip the list, which defeats the gate:
+2
View File
@@ -12,6 +12,8 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode`. No block →
defaults in `.claude/docs/config-resolution.md`.
# Map Systems
When this skill is invoked:
+6 -5
View File
@@ -12,6 +12,8 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode` for this run. No
block → defaults in `.claude/docs/config-resolution.md`.
# Milestone Review
## Insufficient input — check this before producing any report
@@ -32,11 +34,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
+6 -5
View File
@@ -15,6 +15,8 @@ every file write follows `.claude/docs/automation-modes.md`
(collaborative asks always · guided major-only · autonomous logs and proceeds;
`automation_always_ask` categories always prompt).
# Onboard
## Insufficient input — check this before producing any report
**If the inputs this skill needs do not exist, the answer is "could not run" —
@@ -33,11 +35,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
+2
View File
@@ -15,6 +15,8 @@ every file write follows `.claude/docs/automation-modes.md`
(collaborative asks always · guided major-only · autonomous logs and proceeds;
`automation_always_ask` categories always prompt).
# Patch Notes
## Provenance check — before reading any history
**Confirm the history you are about to read belongs to THIS game.** Run this
+18 -13
View File
@@ -7,11 +7,13 @@ allowed-tools: Read, Glob, Grep, Write, Bash, Bash(bash "*/.claude/skills/perf-p
model: sonnet
---
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys performance.enforce,automation`
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys performance.enforce,automation,workflow`
Resolved above — use as-is. No block → defaults in
`.claude/docs/config-resolution.md`.
# Performance Profile
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).
@@ -34,11 +36,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
@@ -81,13 +82,17 @@ Read the argument:
record of what it agreed to, and design docs are the fallback, not the source:
```bash
source "${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/yaml-helper.sh" 2>/dev/null
get_effective_yaml_key performance.target_framerate
get_effective_yaml_key performance.frame_budget_ms
get_effective_yaml_key performance.draw_call_limit
get_effective_yaml_key performance.memory_ceiling_mb
(cd "${CLAUDE_SKILL_DIR}/../../.." && source .claude/hooks/yaml-helper.sh 2>/dev/null &&
echo "performance.target_framerate: $(get_effective_yaml_key performance.target_framerate)" &&
echo "performance.frame_budget_ms: $(get_effective_yaml_key performance.frame_budget_ms)" &&
echo "performance.draw_call_limit: $(get_effective_yaml_key performance.draw_call_limit)" &&
echo "performance.memory_ceiling_mb: $(get_effective_yaml_key performance.memory_ceiling_mb)")
```
Run it as one command: it loads the helper from the project root, so it works
when the session was started in a subfolder. An empty value after a key means
that budget is not set.
> Written as four literal keys rather than a loop over leaf names, deliberately.
> The dead-settings audit matches the **full dotted key**, so a loop building
> `performance.$k` leaves three of the four spelled nowhere and the audit
@@ -206,7 +211,7 @@ Activate this phase only if any hotspot has Fix Effort rated M or L.
Present significant-effort items and ask the user to choose for each:
- **A) Implement the optimization** (proceed with fix now or schedule it)
- **A) Implement the optimization** (proceed with fix now or schedule it — at `workflow: minimal`, which has no sprints, add it to the brief's build order)
- **B) Reduce feature scope** (run `/scope-check [feature]` to analyze trade-offs)
- **C) Accept the performance hit and defer to Polish phase** (log as known issue)
- **D) Escalate to technical-director for an architectural decision** (run `/architecture-decision`)
@@ -228,7 +233,7 @@ other outcome is the `NOT ASSESSED — NO DATA` path above.
- If bottlenecks require architectural change: run `/architecture-decision`.
- If scope reduction is needed: run `/scope-check [feature]`.
- To schedule optimizations: run `/sprint-plan update`.
- To schedule optimizations: run `/sprint-plan update` (at `workflow: minimal`, which has no sprints, add them to the brief's build order instead).
### Rules
- Never optimize without measuring first — gut feelings about performance are unreliable
+2
View File
@@ -12,6 +12,8 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode` for this run. No
block → defaults in `.claude/docs/config-resolution.md`.
# Playtest Report
## Phase 1: Parse Arguments
+11 -547
View File
@@ -12,7 +12,7 @@ model: sonnet
Resolved above — use as-is; `--review` overrides `review_mode` for this run. No
block → defaults in `.claude/docs/config-resolution.md`.
# Prototype
## Purpose
@@ -34,581 +34,45 @@ before committing to Production, run `/vertical-slice` instead.
## Phase 1: Define the Question
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).
**Check for spike mode:** If `--spike` was passed, skip to the **Spike Mode** section
at the bottom of this skill.
**Check for a carry-forward note:** Glob `prototypes/*/PIVOT-NOTE.md`. If one
exists for this concept (or an earlier version of it), read it and start from its
revised hypothesis instead of forming one from scratch — say which note you used.
Then, unless `--spike` sent you to Spike Mode, use `AskUserQuestion` to confirm
intent before proceeding — with or without a carry-forward note:
- **Prompt**: "How would you like to use this prototype session?"
- **Options**:
- `Prototype this concept` — build a throwaway build to validate the core idea is fun before writing GDDs (1–3 days)
- `Skip — concept already proven` — I have enough evidence this works; log it and proceed directly to design
- `Mid-production spike` — I'm already in Production and want to test a specific mechanic or technical question quickly (~4 hours, no phase gate implications)
**If "Skip — concept already proven":**
Ask (plain text, not a widget): "What evidence do you have that the concept works?"
Record the one-line answer, then stop. Note: "Concept prototype skipped — evidence:
[answer]." Suggest next step: `/map-systems` or `/design-system [mechanic]`.
**If "Mid-production spike"**: skip to the **Spike Mode** section below.
**If "Prototype this concept"**: continue with Phase 1 below.
---
**A note on prototype strategy:** The research on successful indie development
is consistent — building 2-3 concept variants and letting the best one win is
far more likely to succeed than iterating one concept until it works. This is
your first prototype, not necessarily your only one. If this prototype produces
a PIVOT verdict, consider whether to refine this concept OR start fresh with a
different angle on the same game idea and prototype that instead.
**Game jam as a prototype vehicle:** If you're planning a concept prototype anyway,
consider timing it to a game jam (Ludum Dare, GMTK Game Jam, Global Game Jam). Jams
provide a forced timebox (48-72 hours), instant distribution to thousands of players
who rate and review early builds, and a deadline that prevents scope creep by design.
Many shipped games (Celeste, VVVVVV) began as jam prototypes. Not required — but
worth considering if the timing is right.
Read the concept description from the argument. Before building anything, define
the **falsifiable hypothesis** this prototype must answer:
> *"If the player [does X], they will feel [Y] — we will know this is true if [measurable signal Z]."*
Good: "If the player swings on grapple hooks, traversal will feel fluid — we'll know if
players chain 3+ swings without stopping within 2 minutes of picking it up."
Bad: "Does this feel fun?" ← not testable, not falsifiable.
**If the concept is too vague to form a hypothesis, stop here.** Ask the user to
narrow the question before proceeding. A prototype without a clear question wastes time.
Also ask: **"What is the riskiest assumption in this concept?"** That is the first
thing the prototype should test — not the easiest part, the riskiest.
---
**Read `references/1-question.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 2: Load Concept Context
Read `design/gdd/game-concept.md` — or `design/game-brief.md`, the one-page brief
that replaces it at `rigor: minimal` — if either exists. Extract:
- Core fantasy (what the player is supposed to feel)
- Core loop (the moment-to-moment action being tested)
Determine the engine and language in use: read `engine.name` and
`engine.language` from `project.yaml`. For each field, if its key is absent or
empty (including when `project.yaml` has no `engine:` block), fall back to
`CLAUDE.md` and `.claude/docs/technical-preferences.md`. Treat a
`[TO BE CONFIGURED]` value as not set.
---
**Read `references/2-load-context.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 3: Choose the Prototype Path
Select the prototype path. If `--path [html|engine|paper]` was passed, use that.
Otherwise, use this quick-reference first, then read the full path details below:
| Genre | Recommended path | Key reason |
|-------|-----------------|------------|
| Platformer / action / fighter | **Engine** | Feel IS the hypothesis; browser latency produces false results |
| Racing / sports | **Engine** | Same — timing and physics feedback are the point |
| Top-down shooter / twin-stick | **Engine** | Aim feel is timing-sensitive |
| Puzzle (logic) | **HTML** or **Paper** | Timing is not the point; logic and clarity are |
| Card game | **Paper** first | Fastest iteration by hand before touching code |
| Narrative / visual novel | **Paper** (Twine / Ink / Yarn Spinner) | Story is the mechanic — test it without code overhead |
| Strategy / 4X / city builder | **Paper** (spreadsheet sim) | Validate economy and progression rules before building |
| Roguelike (systems-heavy) | **Paper** → Engine | Validate that the ruleset is interesting before building |
| Idle / clicker / incremental | **HTML** | Turn-based logic, no feel sensitivity required |
| Rhythm game | **Paper** first (design levels in audio) | Design levels before the engine exists |
| RPG / open world | **Paper** → Engine | Systems complexity: validate rules, then validate feel |
| Horror / atmospheric | **Engine** | Atmosphere requires real rendering |
**Rule of thumb:** "Does this feel right?" → Engine. "Are these rules interesting?" → Paper. "Is this logic correct?" → HTML or Paper.
### Path: HTML (browser-playable)
**Best for:** Puzzle games, card games, turn-based strategy, word games, idle games,
top-down logic games. Anything where timing precision doesn't matter.
**Reliability:** ~85–90% one-shot. The agent writes a single self-contained HTML
file the user opens in a browser — no install required.
**Limitation — browser latency lies about game feel.** Browsers introduce
50–133ms of rendering variance. This makes HTML prototypes fundamentally unreliable
for action games, platformers, fighting games, or anything where input timing,
jump arcs, or collision feel are what you're testing. If feel is the hypothesis,
use the Engine path instead.
**Alternative tools for this path:** PICO-8 (extreme constraints, great for retro
arcade concepts, web-export in one command), Phaser.js (more capable browser game
framework, still no install needed), or Twine (narrative/choice-based games).
These are faster than raw HTML for their respective genres — suggest them if appropriate.
**Output:** A single `prototype.html` (or PICO-8/Phaser equivalent) the user opens in any browser.
**Distribution — the HTML path's biggest advantage:** Unlike Engine prototypes, this
build can reach real players globally in minutes. Use this actively:
- **itch.io** — upload the file, share the link, get play counts and written feedback
within hours. Free. The indie community plays rough builds here without expecting
polish. This is genuine external validation at zero cost.
- **Loom + file share** — share via Google Drive/Dropbox, ask someone to record their
screen + audio with Loom while playing. You get a video of real first-impression
reactions and confusion without synchronous scheduling.
- **r/playmygame or r/WebGames** (Reddit) — active communities that specifically
test early builds and give unsolicited honest feedback.
- **Game dev Discord servers** (GMTK, Brackeys, GameDev.tv) — members test each
other's prototypes routinely; an HTML file is the easiest possible ask.
---
### Path: Engine (engine project)
**Best for:** Action games, platformers, physics-heavy games, anything where
moment-to-moment feel IS the hypothesis. Use this when HTML latency would lie about
the result.
**Reliability:** ~50–60% one-shot. Expect 2–4 rounds of iteration — this is
normal, not a failure.
**Limitation — requires engine installed and running.** This path is a
multi-turn collaborative loop:
1. Agent writes the code
2. User runs it in the engine
3. User reports errors or observations
4. Agent fixes and iterates
**Sunk cost rule:** If the user has been iterating for more than 2 hours without
reaching a playable state, stop. The scope is too large or the question is wrong.
Reframe the hypothesis and simplify aggressively, or switch to Paper path.
**Output:** A minimal runnable engine project in `prototypes/[name]-concept/`.
**Lighter alternative — Love2D (Lua):** If the project engine (Godot, Unity, Unreal)
feels too heavy to stand up for a throwaway build, consider Love2D — a minimal 2D
framework that installs in minutes, requires no project scaffolding, and renders
natively with no browser latency. Used by many indie devs for rapid 2D action and
platformer prototypes (Balatro prototyped in Love2D; Nuclear Throne's early builds
used it). It sits between HTML overhead and full engine overhead: heavier than
opening a browser, lighter than setting up a full engine project. Best for 2D
action/platformer feel validation when the project engine is 3D-first or takes
significant time to configure.
---
### Path: Paper (rules document + play log)
**Best for:** Strategy games, card games, board game-style mechanics, economy
systems, progression loops, any game where the logic can be simulated by hand.
Works for any genre when you need to validate rules, not feel.
**Reliability:** 100%. No code, no engine, no install.
**Limitation — cannot validate moment-to-moment feel.** Paper prototypes prove
that the rules are internally consistent and the decisions are interesting. They
cannot tell you whether jumping feels right or whether explosions feel satisfying.
**Paper playtest observation protocol (run this with 5+ people):**
1. Brief the rules once. Hand them the rule summary sheet. Then step back.
2. Do NOT explain further. Do NOT help. Do NOT clarify. Confusion is data.
3. Watch silently. Note every moment they slow down, re-read, or ask a question.
4. After the session, ask one question only: "What was confusing?" — not "Did you like it?"
5. Use fresh testers for each iteration. The same person cannot give new first-impression data.
6. If 3+ testers hit the same confusion point, that rule is broken — redesign it before re-testing.
**Output:** A printable rules document + a completed play log showing one simulated session.
**Narrative tools for this path:** For dialogue-heavy and story-driven games, skip the
generic rules doc — use a dedicated narrative scripting tool instead:
- **Twine** — zero-code hypertext fiction; ideal for branching structure experiments and choice-impact testing
- **Ink** (Inkle) — plain-text scripting language used in *80 Days*, *Heaven's Vault*, and *Overboard*; exports directly to Unity and Godot
- **Yarn Spinner** — dialogue scripting used in *A Short Hike*, *DREDGE*, and *Night in the Woods*; integrates natively with Unity and Godot
All three let you write and playtest branching dialogue in minutes. Key metric for
narrative prototypes: **time to first emotional beat** — how many exchanges before
the player feels something? If it takes more than 3-4 exchanges, the opening is too slow.
---
Assess which path best fits the hypothesis, then use `AskUserQuestion` with your
recommendation pre-stated:
- **Prompt**: "Which prototype path would you like to use? (Based on your concept, I'd recommend [path] — [one sentence reason].)"
- **Options**:
- `HTML — browser prototype` — puzzle, card, turn-based, strategy, idle. Opens by double-clicking, no install. 85–90% reliable. **Not suitable for action games** — browser latency lies about feel.
- `Engine — native prototype` — action, platformer, physics, or anything where feel IS the hypothesis. 50–60% one-shot; 2–4 iteration rounds are normal. Requires engine installed.
- `Paper — rules document + play log` — strategy, economy, logic, board-game-style mechanics. 100% reliable. Cannot validate feel.
---
**Read `references/3-choose-path.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 4: Plan the Prototype
Define in 3–5 bullet points the minimum viable prototype:
- What is the falsifiable hypothesis?
- What is the riskiest assumption — and how does this prototype test it first?
- What is the absolute minimum needed to answer the question?
- What is explicitly cut? (menus, save systems, error handling, polish, architecture — all of it)
**Scope constraint:** A concept prototype tests ONE mechanic — not the whole game.
If scope covers more than one mechanic, cut it down. When in doubt, cut more.
Present this plan to the user before building. Get confirmation before proceeding.
Name the checkpoint file in that confirmation: "May I record this plan in
`production/session-state/active.md`?"
Once confirmed, write a session checkpoint to `production/session-state/active.md`
(create `production/session-state/` if it does not exist). Include: concept name,
hypothesis, path chosen, scope bullet points, and current phase ("Phase 5 —
Implement"). This lets the next session resume without starting over if the session
ends mid-build — especially important for multi-day Engine path work.
---
**Read `references/4-plan.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 5: Implement
Ask: "May I create the prototype directory at `prototypes/[concept-name]-concept/`
and begin implementation?"
If yes, create the directory. Every file must begin with:
```
[comment] PROTOTYPE - NOT FOR PRODUCTION
[comment] Question: [Core question being tested]
[comment] Date: [Current date]
```
Write `[comment]` in each file's own comment syntax — `#` in GDScript (`.gd`) and
Python, `//` in C#, C++ and JavaScript, `--` in Lua, `<!-- … -->` in HTML and
Markdown. A header in another language's syntax is a parse error, not a label.
Files that cannot hold a comment (JSON, engine-generated scene and project
files) are exempt.
Standards are intentionally relaxed:
- Hardcode values freely
- Use placeholder assets (colored rectangles, debug shapes)
- Skip error handling entirely
- Use the simplest approach that works
- Copy code rather than importing from production
- No architecture, no patterns, no abstractions
**Do not add polish.** No menus, no game over screens, no music, no tutorial text
unless the tutorial IS the mechanic being tested. Every addition beyond the
hypothesis is waste.
**Playtesting tip:** If you have access to anyone who hasn't seen the game —
friends, family, strangers online — watching them play without explanation gives
far better signal than testing it yourself. Watch silently; don't guide them.
Confusion is data. Ask one question after: "What was confusing?" Not "Did you
like it?"
**No external testers available?** Use rotation: if you built system A, you're a
naive tester for system B. In a two-person team this works well. Solo developer?
Step away for 2-3 days before playing fresh — you won't have perfect first-impression
signal, but you'll surface the worst blockers. Another option: play your own
prototype as a speedrun (force yourself through it in 5 minutes without stopping
to fix things) — the friction you feel is what strangers will hit.
**Want more granular UX data?** Ask the tester to **think aloud** as they play —
narrate their thoughts in real time: "I'm pressing space... nothing happened... is
that the jump key?" This surfaces confusion the moment it happens rather than
waiting for a post-play debrief. Best for UI/UX and onboarding clarity. Silent
observation is still better for testing raw feel; think-aloud changes how people
play slightly but gives much richer data about why they're confused.
**HTML prototype?** itch.io, Reddit (r/playmygame), and Discord (GMTK, Brackeys)
let you reach strangers today at zero cost — see the distribution options in the
HTML path section above.
**Testing AI, NPC, or complex system behavior before writing the code?** Use the
**Wizard of Oz** technique: one person plays normally while a second person secretly
controls the NPC, enemy, or system behavior in real time — making the decisions a
human would make, not an algorithm. The player believes it's automated. This lets
you validate whether your AI design *feels right* before writing a single line of
pathfinding or decision tree code. When you observe what responses the human
controller naturally produces, you learn exactly what the AI needs to do.
### Engine path: multi-turn loop
After writing the initial code:
> "The prototype files are written. Run the project in your engine now.
> If there are errors, paste them here and I'll fix them. If it runs,
> describe what you see and whether it feels like it's answering the question."
Iterate until the prototype is playable. Each loop:
1. User runs → reports errors or observations
2. Agent fixes errors or adjusts the mechanic
3. Repeat until playable or sunk cost rule triggers
### HTML path: single output
Write a single `prototype.html` to `prototypes/[concept-name]-concept/`. Include
all styles, logic, and assets inline. The file must be openable by double-clicking
with no server required.
### Paper path: document + log
Write `prototypes/[concept-name]-concept/rules.md` (the game rules) and
`prototypes/[concept-name]-concept/play-log.md` (a simulated session walking
through one complete play cycle step by step with dice rolls, decisions, and
outcomes narrated).
---
**Read `references/5-implement.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 6: Playtest Debrief
The prototype is built. Now hand it to the user and capture what they actually
experienced. Do NOT skip to report generation — the report is only as good as the
observations you collect here.
**For HTML path:** Say exactly this:
> "The prototype is ready. Open `prototypes/[name]-concept/prototype.html` in your
> browser and play it. Take as long as you need. Don't rush through it — try to
> approach it the way a new player would. Come back here when you're done."
**For Engine path:** The multi-turn iteration loop already captured errors and
behavior. Now ask for the overall assessment:
> "Now that it's running — play through it a few times as if you're the player,
> not the developer. Come back when you have a feel for it."
**For Paper path:** Say exactly this:
> "Read through `prototypes/[name]-concept/rules.md` and walk through the
> `play-log.md` as if you're playing it for the first time. If you have someone
> nearby, try running the rules with them. Come back when you've seen at least one
> full play cycle."
**If nobody can play it this session**, do not ask for a verdict and do not infer
one from how the build looks: the recommendation is **NOT ASSESSED — built, not
played**. Write the report with that verdict (Phase 7, asking first) and name the
next step — play it, then re-run this debrief.
Once the user returns, ask these questions **one at a time** — wait for each answer
before asking the next:
1. **Hypothesis check:**
> "The hypothesis was: [restate the hypothesis from Phase 1]. Did it hold up —
> CONFIRMED, PARTIALLY CONFIRMED, or REFUTED? Tell me what you saw."
2. **Best moment:**
> "What was the moment — if any — where it felt like it was working? Be specific."
3. **Worst moment:**
> "What was the most frustrating, confusing, or broken moment? Be specific —
> not 'it felt slow' but 'the jump took about half a second to respond and it
> felt like I was fighting the controls'."
4. **Surprise:**
> "Did anything happen that you didn't expect — good or bad?"
5. **Verdict:**
> "PROCEED, PIVOT, or KILL — and one sentence why."
Collect all answers before moving to report generation. If any answer is vague
("it felt fine", "pretty good"), ask a follow-up: "Can you be more specific?
What exactly felt fine about it?" Precise observations make the report useful.
Vague ones make it useless.
---
**Read `references/6-debrief.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 7: Generate Prototype Report
Read `.claude/docs/templates/prototype-report.md` to get the report structure.
Fill in every section based on what was observed during this session. Replace all
placeholder text with real observations — no generic filler.
Ask: "May I write this report to `prototypes/[concept-name]-concept/REPORT.md`
and add its row to `prototypes/index.md`?"
If yes, write the file. Then update `prototypes/index.md` (create if it does not
exist) — append one row to the concept prototype table: concept name, date, path
used, verdict (PROCEED/PIVOT/KILL, or NOT ASSESSED when nobody has played it), and a link to the REPORT.md. If a PIVOT chain
exists (prior PIVOT-NOTE.md in a related concept folder), note the chain. This file
is the project's complete history of what was tried and what was learned.
---
**Read `references/7-report.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 8: Creative Director Review
**Review mode check:**
- `solo` → skip. Note: "CD-PLAYTEST skipped — Solo mode."
- `lean` → skip. Note: "CD-PLAYTEST skipped — Lean mode."
- `full` → spawn `creative-director` via `Agent` using gate **CD-PLAYTEST** if
`design/gdd/game-concept.md` exists with game pillars defined, or
`design/game-brief.md` exists (the `rigor: minimal` brief has no pillars — its
pitch and "what they feel" line stand in). If neither is available, note:
"CD-PLAYTEST skipped — game pillars not yet defined at concept prototype stage."
Pass: the full REPORT.md content, the original hypothesis, and game pillars /
core fantasy from `design/gdd/game-concept.md` (or the brief's pitch and "what
they feel" line from `design/game-brief.md`).
The creative director evaluates the result against the game's creative vision and
returns one of the gate's verdicts — APPROVE, CONCERNS or REJECT — or NOT
ASSESSED when it could not judge. Apply it to the recommendation:
- **APPROVE** → the recommendation stands.
- **CONCERNS** → show the concerns alongside the recommendation, then use
`AskUserQuestion`: `Revise the recommendation` / `Accept with noted concerns` /
`Discuss further`. The user decides; the director does not.
- **REJECT** (the core fantasy is not present) → a PROCEED recommendation cannot
stand. Use `AskUserQuestion` to ask the user to choose `PIVOT` or `KILL`, and run
Phase 9 for that choice. A PIVOT or KILL recommendation stands.
- **NOT ASSESSED** (the director lacked an input — `.claude/docs/director-gates.md`)
→ not an approval. Name what was missing; supply it and re-run the gate, or
record the review as NOT ASSESSED and let the user decide whether the
recommendation stands unreviewed.
When the director returned CONCERNS, REJECT or NOT ASSESSED, ask "May I update
`prototypes/[concept-name]-concept/REPORT.md` and its `prototypes/index.md`
row?", then record the director's verdict and reason in REPORT.md, and the final
recommendation in both if it changed.
---
**Read `references/8-cd-review.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 9: Summary and Next Steps
Output a summary: the hypothesis, the result, and the final recommendation.
Link to `prototypes/[concept-name]-concept/REPORT.md`.
**If PROCEED:**
Your concept prototype validated the core idea. Now design it properly, informed by
what you just learned.
At `workflow: minimal`: `/create-stories` (from the brief), then `/dev-story`
on the first story — the rest of this list is the `standard`/`full` path.
Recommended path (in order, `standard`/`full`):
1. `/design-review design/gdd/game-concept.md` — validate the concept doc against what the prototype revealed
2. `/gate-check` — confirm readiness to advance to Systems Design
3. `/art-bible` — define visual identity (optional but worth doing before GDDs)
4. `/map-systems` — decompose the concept into all game systems
5. `/design-system [mechanic]` — GDD for each MVP system; use prototype learnings
in the Tuning Knobs and Formulas sections
6. `/review-all-gdds` — cross-system consistency check
**Note:** If you used the HTML path and feel is still uncertain, consider running
a quick engine path prototype targeting feel before writing GDDs.
**If PIVOT:**
Before routing to the next prototype, capture the carry-forward note. Ask these
two questions (plain text, one at a time):
1. "What specifically worked in this prototype that we should preserve in the next version?"
2. "What is the single most important thing to change?"
Ask: "May I write this to `prototypes/[concept-name]-concept/PIVOT-NOTE.md`?"
If yes, write the file with: original hypothesis, what to keep, what to change, and
the revised hypothesis for the next prototype. The next `/prototype` run picks it
up at the start of Phase 1.
- Run `/prototype [revised-concept]` to test the adjusted direction
- Or `/brainstorm [hint]` if the concept needs more fundamental rethinking
**If KILL:**
Before moving on, run this check to confirm the verdict is sound and not temporary frustration:
- [ ] Core mechanic still unclear to testers after 2+ playtests?
- [ ] No "fun moment" (smile, laugh, or retry by choice) observed in any session?
- [ ] 3+ PIVOT iterations on the same concept with no clear improvement?
- [ ] Concept only works when heavily explained or when the dev guides the player?
- [ ] Building this feels like obligation, not excitement?
If 2+ boxes apply → KILL verdict is sound. If 0–1 apply → consider one more focused PIVOT before killing.
**Document the kill in `prototypes/GRAVEYARD.md`** (create if it doesn't exist).
Ask: "May I append this concept to `prototypes/GRAVEYARD.md`?" If yes, add one entry:
```
## [Concept Name] — YYYY-MM-DD
- **Kill reason:** [specific blocker — not "it was boring" but "players never understood the core action"]
- **What worked:** [2-3 things worth carrying forward to future concepts]
- **What failed:** [the specific mechanic, design decision, or scope issue]
- **Next time:** [one explicit action to try differently on a similar concept]
```
This file exists so the same mistake doesn't get made twice on the next concept.
- Run `/brainstorm open` or `/brainstorm [new-hint]` to explore a different concept
- The prototype report is the deliverable — no further action needed
**If NOT ASSESSED (nobody has played it):**
There is no fun evidence yet, so PROCEED, PIVOT and KILL are all unreachable —
report NOT ASSESSED and stop here rather than guess.
- Play it, then run `/prototype [same concept]` again
- The report and the concept index row read NOT ASSESSED until a playtest happens
---
---
**Read `references/9-summary.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Spike Mode
**Triggered by:** `--spike` flag OR "Mid-production spike" entry choice in Phase 1.
**Purpose:** Test a specific technical or design question mid-production, without
the overhead of a full concept prototype workflow. No GDD prerequisites. No phase
gate implications. Hard cap: ~4 hours.
**When to use:**
- You're in Production and want to test whether a new mechanic should be added
- You're unsure if a technical approach will work before building it properly
- A design change is being considered and you want a quick before/after comparison
- A GDD system is proving harder than expected and you want to prototype the hard part
- You need to confirm target hardware can sustain the required framerate before writing gameplay code (**performance spike** — see below)
**Spike Mode workflow (replaces Phases 1–9):**
1. **Define the spike question** (plain text, not a widget): "What specific question does this spike answer? Give me one sentence: 'Can we [do X] using [approach Y]?'"
2. **Choose path** — same AskUserQuestion widget as Phase 3 (HTML / Engine / Paper).
3. **Scope** — maximum 2-3 bullet points. One mechanic, one technical question, nothing else.
4. **Build** — first ask "May I create `prototypes/[concept-name]-spike-[date]/` and build the spike there?" Same relaxed standards and header as the concept prototype. Hard cap: 4 hours. If not demonstrable in 4 hours, the question is too large. Split it.
5. **Observe and decide** — no formal playtest debrief. Ask: "Did the spike answer the question? YES or NO, and why in one sentence."
6. **Write a spike note** (not a full report) to `prototypes/[concept-name]-spike-[date]/SPIKE-NOTE.md` — first ask once for this step and the next, naming both files: "May I write `prototypes/[concept-name]-spike-[date]/SPIKE-NOTE.md` and clear the spike from `production/session-state/active.md`?" The note holds:
- Question tested
- Result (YES it works / NO it doesn't / PARTIAL — needs more investigation)
- What to do next (add to current sprint / investigate further / abandon the idea)
7. **Update `production/session-state/active.md`** to clear the spike and return to the current sprint state.
**No CD gate. No phase gate. No PROCEED/PIVOT/KILL.** Spike results inform decisions; they don't make them. The developer decides whether to add the mechanic/approach to the sprint backlog based on what the spike revealed.
**Performance spike (special case):** If the game involves demanding rendering —
large open worlds, hundreds of simultaneous physics bodies, heavy particle systems,
complex shaders — run a performance spike before writing gameplay code to confirm
the target hardware can sustain the required framerate. This is distinct from other
spikes in two ways:
- The question is "can the engine render [scene X] at 60fps on [minimum spec hardware]?"
not "does this mechanic feel good?"
- The output is a benchmark number, not a feel verdict
- No gameplay logic is needed — just the maximum intended scene load (terrain, draw
calls, physics objects, particles) running at once
- Build time stays within the ~4-hour cap; the spike is setting up the rendering
load, not the game
- If the answer is NO at this scope, this is an architecture or scope constraint
that affects everything downstream — better to surface it now than during Sprint 8
---
**Read `references/spike-mode.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
### Important Constraints
@@ -0,0 +1,69 @@
# /prototype — Phase 1: Define the Question
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 1: Define the Question
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).
**Check for spike mode:** If `--spike` was passed, skip to the **Spike Mode** section
at the bottom of this skill.
**Check for a carry-forward note:** Glob `prototypes/*/PIVOT-NOTE.md`. If one
exists for this concept (or an earlier version of it), read it and start from its
revised hypothesis instead of forming one from scratch — say which note you used.
Then, unless `--spike` sent you to Spike Mode, use `AskUserQuestion` to confirm
intent before proceeding — with or without a carry-forward note:
- **Prompt**: "How would you like to use this prototype session?"
- **Options**:
- `Prototype this concept` — build a throwaway build to validate the core idea is fun before writing GDDs (1–3 days)
- `Skip — concept already proven` — I have enough evidence this works; log it and proceed directly to design
- `Mid-production spike` — I'm already in Production and want to test a specific mechanic or technical question quickly (~4 hours, no phase gate implications)
**If "Skip — concept already proven":**
Ask (plain text, not a widget): "What evidence do you have that the concept works?"
Record the one-line answer, then stop. Note: "Concept prototype skipped — evidence:
[answer]." Suggest next step: `/map-systems` or `/design-system [mechanic]`.
**If "Mid-production spike"**: skip to the **Spike Mode** section below.
**If "Prototype this concept"**: continue with Phase 1 below.
---
**A note on prototype strategy:** The research on successful indie development
is consistent — building 2-3 concept variants and letting the best one win is
far more likely to succeed than iterating one concept until it works. This is
your first prototype, not necessarily your only one. If this prototype produces
a PIVOT verdict, consider whether to refine this concept OR start fresh with a
different angle on the same game idea and prototype that instead.
**Game jam as a prototype vehicle:** If you're planning a concept prototype anyway,
consider timing it to a game jam (Ludum Dare, GMTK Game Jam, Global Game Jam). Jams
provide a forced timebox (48-72 hours), instant distribution to thousands of players
who rate and review early builds, and a deadline that prevents scope creep by design.
Many shipped games (Celeste, VVVVVV) began as jam prototypes. Not required — but
worth considering if the timing is right.
Read the concept description from the argument. Before building anything, define
the **falsifiable hypothesis** this prototype must answer:
> *"If the player [does X], they will feel [Y] — we will know this is true if [measurable signal Z]."*
Good: "If the player swings on grapple hooks, traversal will feel fluid — we'll know if
players chain 3+ swings without stopping within 2 minutes of picking it up."
Bad: "Does this feel fun?" ← not testable, not falsifiable.
**If the concept is too vague to form a hypothesis, stop here.** Ask the user to
narrow the question before proceeding. A prototype without a clear question wastes time.
Also ask: **"What is the riskiest assumption in this concept?"** That is the first
thing the prototype should test — not the easiest part, the riskiest.
---
@@ -0,0 +1,19 @@
# /prototype — Phase 2: Load Concept Context
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 2: Load Concept Context
Read `design/gdd/game-concept.md` — or `design/game-brief.md`, the one-page brief
that replaces it at `rigor: minimal` — if either exists. Extract:
- Core fantasy (what the player is supposed to feel)
- Core loop (the moment-to-moment action being tested)
Determine the engine and language in use: read `engine.name` and
`engine.language` from `project.yaml`. For each field, if its key is absent or
empty (including when `project.yaml` has no `engine:` block), fall back to
`CLAUDE.md` and `.claude/docs/technical-preferences.md`. Treat a
`[TO BE CONFIGURED]` value as not set.
---
@@ -0,0 +1,147 @@
# /prototype — Phase 3: Choose the Prototype Path
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 3: Choose the Prototype Path
**In this file:**
- Path: HTML (browser-playable)
- Path: Engine (engine project)
- Path: Paper (rules document + play log)
Select the prototype path. If `--path [html|engine|paper]` was passed, use that.
Otherwise, use this quick-reference first, then read the full path details below:
| Genre | Recommended path | Key reason |
|-------|-----------------|------------|
| Platformer / action / fighter | **Engine** | Feel IS the hypothesis; browser latency produces false results |
| Racing / sports | **Engine** | Same — timing and physics feedback are the point |
| Top-down shooter / twin-stick | **Engine** | Aim feel is timing-sensitive |
| Puzzle (logic) | **HTML** or **Paper** | Timing is not the point; logic and clarity are |
| Card game | **Paper** first | Fastest iteration by hand before touching code |
| Narrative / visual novel | **Paper** (Twine / Ink / Yarn Spinner) | Story is the mechanic — test it without code overhead |
| Strategy / 4X / city builder | **Paper** (spreadsheet sim) | Validate economy and progression rules before building |
| Roguelike (systems-heavy) | **Paper** → Engine | Validate that the ruleset is interesting before building |
| Idle / clicker / incremental | **HTML** | Turn-based logic, no feel sensitivity required |
| Rhythm game | **Paper** first (design levels in audio) | Design levels before the engine exists |
| RPG / open world | **Paper** → Engine | Systems complexity: validate rules, then validate feel |
| Horror / atmospheric | **Engine** | Atmosphere requires real rendering |
**Rule of thumb:** "Does this feel right?" → Engine. "Are these rules interesting?" → Paper. "Is this logic correct?" → HTML or Paper.
### Path: HTML (browser-playable)
**Best for:** Puzzle games, card games, turn-based strategy, word games, idle games,
top-down logic games. Anything where timing precision doesn't matter.
**Reliability:** ~85–90% one-shot. The agent writes a single self-contained HTML
file the user opens in a browser — no install required.
**Limitation — browser latency lies about game feel.** Browsers introduce
50–133ms of rendering variance. This makes HTML prototypes fundamentally unreliable
for action games, platformers, fighting games, or anything where input timing,
jump arcs, or collision feel are what you're testing. If feel is the hypothesis,
use the Engine path instead.
**Alternative tools for this path:** PICO-8 (extreme constraints, great for retro
arcade concepts, web-export in one command), Phaser.js (more capable browser game
framework, still no install needed), or Twine (narrative/choice-based games).
These are faster than raw HTML for their respective genres — suggest them if appropriate.
**Output:** A single `prototype.html` (or PICO-8/Phaser equivalent) the user opens in any browser.
**Distribution — the HTML path's biggest advantage:** Unlike Engine prototypes, this
build can reach real players globally in minutes. Use this actively:
- **itch.io** — upload the file, share the link, get play counts and written feedback
within hours. Free. The indie community plays rough builds here without expecting
polish. This is genuine external validation at zero cost.
- **Loom + file share** — share via Google Drive/Dropbox, ask someone to record their
screen + audio with Loom while playing. You get a video of real first-impression
reactions and confusion without synchronous scheduling.
- **r/playmygame or r/WebGames** (Reddit) — active communities that specifically
test early builds and give unsolicited honest feedback.
- **Game dev Discord servers** (GMTK, Brackeys, GameDev.tv) — members test each
other's prototypes routinely; an HTML file is the easiest possible ask.
---
### Path: Engine (engine project)
**Best for:** Action games, platformers, physics-heavy games, anything where
moment-to-moment feel IS the hypothesis. Use this when HTML latency would lie about
the result.
**Reliability:** ~50–60% one-shot. Expect 2–4 rounds of iteration — this is
normal, not a failure.
**Limitation — requires engine installed and running.** This path is a
multi-turn collaborative loop:
1. Agent writes the code
2. User runs it in the engine
3. User reports errors or observations
4. Agent fixes and iterates
**Sunk cost rule:** If the user has been iterating for more than 2 hours without
reaching a playable state, stop. The scope is too large or the question is wrong.
Reframe the hypothesis and simplify aggressively, or switch to Paper path.
**Output:** A minimal runnable engine project in `prototypes/[name]-concept/`.
**Lighter alternative — Love2D (Lua):** If the project engine (Godot, Unity, Unreal)
feels too heavy to stand up for a throwaway build, consider Love2D — a minimal 2D
framework that installs in minutes, requires no project scaffolding, and renders
natively with no browser latency. Used by many indie devs for rapid 2D action and
platformer prototypes (Balatro prototyped in Love2D; Nuclear Throne's early builds
used it). It sits between HTML overhead and full engine overhead: heavier than
opening a browser, lighter than setting up a full engine project. Best for 2D
action/platformer feel validation when the project engine is 3D-first or takes
significant time to configure.
---
### Path: Paper (rules document + play log)
**Best for:** Strategy games, card games, board game-style mechanics, economy
systems, progression loops, any game where the logic can be simulated by hand.
Works for any genre when you need to validate rules, not feel.
**Reliability:** 100%. No code, no engine, no install.
**Limitation — cannot validate moment-to-moment feel.** Paper prototypes prove
that the rules are internally consistent and the decisions are interesting. They
cannot tell you whether jumping feels right or whether explosions feel satisfying.
**Paper playtest observation protocol (run this with 5+ people):**
1. Brief the rules once. Hand them the rule summary sheet. Then step back.
2. Do NOT explain further. Do NOT help. Do NOT clarify. Confusion is data.
3. Watch silently. Note every moment they slow down, re-read, or ask a question.
4. After the session, ask one question only: "What was confusing?" — not "Did you like it?"
5. Use fresh testers for each iteration. The same person cannot give new first-impression data.
6. If 3+ testers hit the same confusion point, that rule is broken — redesign it before re-testing.
**Output:** A printable rules document + a completed play log showing one simulated session.
**Narrative tools for this path:** For dialogue-heavy and story-driven games, skip the
generic rules doc — use a dedicated narrative scripting tool instead:
- **Twine** — zero-code hypertext fiction; ideal for branching structure experiments and choice-impact testing
- **Ink** (Inkle) — plain-text scripting language used in *80 Days*, *Heaven's Vault*, and *Overboard*; exports directly to Unity and Godot
- **Yarn Spinner** — dialogue scripting used in *A Short Hike*, *DREDGE*, and *Night in the Woods*; integrates natively with Unity and Godot
All three let you write and playtest branching dialogue in minutes. Key metric for
narrative prototypes: **time to first emotional beat** — how many exchanges before
the player feels something? If it takes more than 3-4 exchanges, the opening is too slow.
---
Assess which path best fits the hypothesis, then use `AskUserQuestion` with your
recommendation pre-stated:
- **Prompt**: "Which prototype path would you like to use? (Based on your concept, I'd recommend [path] — [one sentence reason].)"
- **Options**:
- `HTML — browser prototype` — puzzle, card, turn-based, strategy, idle. Opens by double-clicking, no install. 85–90% reliable. **Not suitable for action games** — browser latency lies about feel.
- `Engine — native prototype` — action, platformer, physics, or anything where feel IS the hypothesis. 50–60% one-shot; 2–4 iteration rounds are normal. Requires engine installed.
- `Paper — rules document + play log` — strategy, economy, logic, board-game-style mechanics. 100% reliable. Cannot validate feel.
---
@@ -0,0 +1,28 @@
# /prototype — Phase 4: Plan the Prototype
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 4: Plan the Prototype
Define in 3–5 bullet points the minimum viable prototype:
- What is the falsifiable hypothesis?
- What is the riskiest assumption — and how does this prototype test it first?
- What is the absolute minimum needed to answer the question?
- What is explicitly cut? (menus, save systems, error handling, polish, architecture — all of it)
**Scope constraint:** A concept prototype tests ONE mechanic — not the whole game.
If scope covers more than one mechanic, cut it down. When in doubt, cut more.
Present this plan to the user before building. Get confirmation before proceeding.
Name the checkpoint file in that confirmation: "May I record this plan in
`production/session-state/active.md`?"
Once confirmed, write a session checkpoint to `production/session-state/active.md`
(create `production/session-state/` if it does not exist). Include: concept name,
hypothesis, path chosen, scope bullet points, and current phase ("Phase 5 —
Implement"). This lets the next session resume without starting over if the session
ends mid-build — especially important for multi-day Engine path work.
---
@@ -0,0 +1,96 @@
# /prototype — Phase 5: Implement
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 5: Implement
Ask: "May I create the prototype directory at `prototypes/[concept-name]-concept/`
and begin implementation?"
If yes, create the directory. Every file must begin with:
```
[comment] PROTOTYPE - NOT FOR PRODUCTION
[comment] Question: [Core question being tested]
[comment] Date: [Current date]
```
Write `[comment]` in each file's own comment syntax — `#` in GDScript (`.gd`) and
Python, `//` in C#, C++ and JavaScript, `--` in Lua, `<!-- … -->` in HTML and
Markdown. A header in another language's syntax is a parse error, not a label.
Files that cannot hold a comment (JSON, engine-generated scene and project
files) are exempt.
Standards are intentionally relaxed:
- Hardcode values freely
- Use placeholder assets (colored rectangles, debug shapes)
- Skip error handling entirely
- Use the simplest approach that works
- Copy code rather than importing from production
- No architecture, no patterns, no abstractions
**Do not add polish.** No menus, no game over screens, no music, no tutorial text
unless the tutorial IS the mechanic being tested. Every addition beyond the
hypothesis is waste.
**Playtesting tip:** If you have access to anyone who hasn't seen the game —
friends, family, strangers online — watching them play without explanation gives
far better signal than testing it yourself. Watch silently; don't guide them.
Confusion is data. Ask one question after: "What was confusing?" Not "Did you
like it?"
**No external testers available?** Use rotation: if you built system A, you're a
naive tester for system B. In a two-person team this works well. Solo developer?
Step away for 2-3 days before playing fresh — you won't have perfect first-impression
signal, but you'll surface the worst blockers. Another option: play your own
prototype as a speedrun (force yourself through it in 5 minutes without stopping
to fix things) — the friction you feel is what strangers will hit.
**Want more granular UX data?** Ask the tester to **think aloud** as they play —
narrate their thoughts in real time: "I'm pressing space... nothing happened... is
that the jump key?" This surfaces confusion the moment it happens rather than
waiting for a post-play debrief. Best for UI/UX and onboarding clarity. Silent
observation is still better for testing raw feel; think-aloud changes how people
play slightly but gives much richer data about why they're confused.
**HTML prototype?** itch.io, Reddit (r/playmygame), and Discord (GMTK, Brackeys)
let you reach strangers today at zero cost — see the distribution options in the
HTML path section above.
**Testing AI, NPC, or complex system behavior before writing the code?** Use the
**Wizard of Oz** technique: one person plays normally while a second person secretly
controls the NPC, enemy, or system behavior in real time — making the decisions a
human would make, not an algorithm. The player believes it's automated. This lets
you validate whether your AI design *feels right* before writing a single line of
pathfinding or decision tree code. When you observe what responses the human
controller naturally produces, you learn exactly what the AI needs to do.
### Engine path: multi-turn loop
After writing the initial code:
> "The prototype files are written. Run the project in your engine now.
> If there are errors, paste them here and I'll fix them. If it runs,
> describe what you see and whether it feels like it's answering the question."
Iterate until the prototype is playable. Each loop:
1. User runs → reports errors or observations
2. Agent fixes errors or adjusts the mechanic
3. Repeat until playable or sunk cost rule triggers
### HTML path: single output
Write a single `prototype.html` to `prototypes/[concept-name]-concept/`. Include
all styles, logic, and assets inline. The file must be openable by double-clicking
with no server required.
### Paper path: document + log
Write `prototypes/[concept-name]-concept/rules.md` (the game rules) and
`prototypes/[concept-name]-concept/play-log.md` (a simulated session walking
through one complete play cycle step by step with dice rolls, decisions, and
outcomes narrated).
---
@@ -0,0 +1,59 @@
# /prototype — Phase 6: Playtest Debrief
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 6: Playtest Debrief
The prototype is built. Now hand it to the user and capture what they actually
experienced. Do NOT skip to report generation — the report is only as good as the
observations you collect here.
**For HTML path:** Say exactly this:
> "The prototype is ready. Open `prototypes/[name]-concept/prototype.html` in your
> browser and play it. Take as long as you need. Don't rush through it — try to
> approach it the way a new player would. Come back here when you're done."
**For Engine path:** The multi-turn iteration loop already captured errors and
behavior. Now ask for the overall assessment:
> "Now that it's running — play through it a few times as if you're the player,
> not the developer. Come back when you have a feel for it."
**For Paper path:** Say exactly this:
> "Read through `prototypes/[name]-concept/rules.md` and walk through the
> `play-log.md` as if you're playing it for the first time. If you have someone
> nearby, try running the rules with them. Come back when you've seen at least one
> full play cycle."
**If nobody can play it this session**, do not ask for a verdict and do not infer
one from how the build looks: the recommendation is **NOT ASSESSED — built, not
played**. Write the report with that verdict (Phase 7, asking first) and name the
next step — play it, then re-run this debrief.
Once the user returns, ask these questions **one at a time** — wait for each answer
before asking the next:
1. **Hypothesis check:**
> "The hypothesis was: [restate the hypothesis from Phase 1]. Did it hold up —
> CONFIRMED, PARTIALLY CONFIRMED, or REFUTED? Tell me what you saw."
2. **Best moment:**
> "What was the moment — if any — where it felt like it was working? Be specific."
3. **Worst moment:**
> "What was the most frustrating, confusing, or broken moment? Be specific —
> not 'it felt slow' but 'the jump took about half a second to respond and it
> felt like I was fighting the controls'."
4. **Surprise:**
> "Did anything happen that you didn't expect — good or bad?"
5. **Verdict:**
> "PROCEED, PIVOT, or KILL — and one sentence why."
Collect all answers before moving to report generation. If any answer is vague
("it felt fine", "pretty good"), ask a follow-up: "Can you be more specific?
What exactly felt fine about it?" Precise observations make the report useful.
Vague ones make it useless.
---
@@ -0,0 +1,21 @@
# /prototype — Phase 7: Generate Prototype Report
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 7: Generate Prototype Report
Read `.claude/docs/templates/prototype-report.md` to get the report structure.
Fill in every section based on what was observed during this session. Replace all
placeholder text with real observations — no generic filler.
Ask: "May I write this report to `prototypes/[concept-name]-concept/REPORT.md`
and add its row to `prototypes/index.md`?"
If yes, write the file. Then update `prototypes/index.md` (create if it does not
exist) — append one row to the concept prototype table: concept name, date, path
used, verdict (PROCEED/PIVOT/KILL, or NOT ASSESSED when nobody has played it), and a link to the REPORT.md. If a PIVOT chain
exists (prior PIVOT-NOTE.md in a related concept folder), note the chain. This file
is the project's complete history of what was tried and what was learned.
---
@@ -0,0 +1,42 @@
# /prototype — Phase 8: Creative Director Review
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 8: Creative Director Review
**Review mode check:**
- `solo` → skip. Note: "CD-PLAYTEST skipped — Solo mode."
- `lean` → skip. Note: "CD-PLAYTEST skipped — Lean mode."
- `full` → spawn `creative-director` via `Agent` using gate **CD-PLAYTEST** if
`design/gdd/game-concept.md` exists with game pillars defined, or
`design/game-brief.md` exists (the `rigor: minimal` brief has no pillars — its
pitch and "what they feel" line stand in). If neither is available, note:
"CD-PLAYTEST skipped — game pillars not yet defined at concept prototype stage."
Pass: the full REPORT.md content, the original hypothesis, and game pillars /
core fantasy from `design/gdd/game-concept.md` (or the brief's pitch and "what
they feel" line from `design/game-brief.md`).
The creative director evaluates the result against the game's creative vision and
returns one of the gate's verdicts — APPROVE, CONCERNS or REJECT — or NOT
ASSESSED when it could not judge. Apply it to the recommendation:
- **APPROVE** → the recommendation stands.
- **CONCERNS** → show the concerns alongside the recommendation, then use
`AskUserQuestion`: `Revise the recommendation` / `Accept with noted concerns` /
`Discuss further`. The user decides; the director does not.
- **REJECT** (the core fantasy is not present) → a PROCEED recommendation cannot
stand. Use `AskUserQuestion` to ask the user to choose `PIVOT` or `KILL`, and run
Phase 9 for that choice. A PIVOT or KILL recommendation stands.
- **NOT ASSESSED** (the director lacked an input — `.claude/docs/director-gates.md`)
→ not an approval. Name what was missing; supply it and re-run the gate, or
record the review as NOT ASSESSED and let the user decide whether the
recommendation stands unreviewed.
When the director returned CONCERNS, REJECT or NOT ASSESSED, ask "May I update
`prototypes/[concept-name]-concept/REPORT.md` and its `prototypes/index.md`
row?", then record the director's verdict and reason in REPORT.md, and the final
recommendation in both if it changed.
---
@@ -0,0 +1,85 @@
# /prototype — Phase 9: Summary and Next Steps
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 9: Summary and Next Steps
Output a summary: the hypothesis, the result, and the final recommendation.
Link to `prototypes/[concept-name]-concept/REPORT.md`.
**If PROCEED:**
Your concept prototype validated the core idea. Now design it properly, informed by
what you just learned.
At `workflow: minimal`: `/create-stories` (from the brief), then `/dev-story`
on the first story — the rest of this list is the `standard`/`full` path.
Recommended path (in order, `standard`/`full`):
1. `/design-review design/gdd/game-concept.md` — validate the concept doc against what the prototype revealed
2. `/gate-check` — confirm readiness to advance to Systems Design
3. `/art-bible` — define visual identity (optional but worth doing before GDDs)
4. `/map-systems` — decompose the concept into all game systems
5. `/design-system [mechanic]` — GDD for each MVP system; use prototype learnings
in the Tuning Knobs and Formulas sections
6. `/review-all-gdds` — cross-system consistency check
**Note:** If you used the HTML path and feel is still uncertain, consider running
a quick engine path prototype targeting feel before writing GDDs.
**If PIVOT:**
Before routing to the next prototype, capture the carry-forward note. Ask these
two questions (plain text, one at a time):
1. "What specifically worked in this prototype that we should preserve in the next version?"
2. "What is the single most important thing to change?"
Ask: "May I write this to `prototypes/[concept-name]-concept/PIVOT-NOTE.md`?"
If yes, write the file with: original hypothesis, what to keep, what to change, and
the revised hypothesis for the next prototype. The next `/prototype` run picks it
up at the start of Phase 1.
- Run `/prototype [revised-concept]` to test the adjusted direction
- Or `/brainstorm [hint]` if the concept needs more fundamental rethinking
**If KILL:**
Before moving on, run this check to confirm the verdict is sound and not temporary frustration:
- [ ] Core mechanic still unclear to testers after 2+ playtests?
- [ ] No "fun moment" (smile, laugh, or retry by choice) observed in any session?
- [ ] 3+ PIVOT iterations on the same concept with no clear improvement?
- [ ] Concept only works when heavily explained or when the dev guides the player?
- [ ] Building this feels like obligation, not excitement?
If 2+ boxes apply → KILL verdict is sound. If 0–1 apply → consider one more focused PIVOT before killing.
**Document the kill in `prototypes/GRAVEYARD.md`** (create if it doesn't exist).
Ask: "May I append this concept to `prototypes/GRAVEYARD.md`?" If yes, add one entry:
```
## [Concept Name] — YYYY-MM-DD
- **Kill reason:** [specific blocker — not "it was boring" but "players never understood the core action"]
- **What worked:** [2-3 things worth carrying forward to future concepts]
- **What failed:** [the specific mechanic, design decision, or scope issue]
- **Next time:** [one explicit action to try differently on a similar concept]
```
This file exists so the same mistake doesn't get made twice on the next concept.
- Run `/brainstorm open` or `/brainstorm [new-hint]` to explore a different concept
- The prototype report is the deliverable — no further action needed
**If NOT ASSESSED (nobody has played it):**
There is no fun evidence yet, so PROCEED, PIVOT and KILL are all unreachable —
report NOT ASSESSED and stop here rather than guess.
- Play it, then run `/prototype [same concept]` again
- The report and the concept index row read NOT ASSESSED until a playtest happens
---
---
@@ -0,0 +1,55 @@
# /prototype — Spike Mode
> Part of `/prototype`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
**Triggered by:** `--spike` flag OR "Mid-production spike" entry choice in Phase 1.
**Purpose:** Test a specific technical or design question mid-production, without
the overhead of a full concept prototype workflow. No GDD prerequisites. No phase
gate implications. Hard cap: ~4 hours.
**When to use:**
- You're in Production and want to test whether a new mechanic should be added
- You're unsure if a technical approach will work before building it properly
- A design change is being considered and you want a quick before/after comparison
- A GDD system is proving harder than expected and you want to prototype the hard part
- You need to confirm target hardware can sustain the required framerate before writing gameplay code (**performance spike** — see below)
**Spike Mode workflow (replaces Phases 1–9):**
1. **Define the spike question** (plain text, not a widget): "What specific question does this spike answer? Give me one sentence: 'Can we [do X] using [approach Y]?'"
2. **Choose path** — same AskUserQuestion widget as Phase 3 (HTML / Engine / Paper).
3. **Scope** — maximum 2-3 bullet points. One mechanic, one technical question, nothing else.
4. **Build** — first ask "May I create `prototypes/[concept-name]-spike-[date]/` and build the spike there?" Same relaxed standards and header as the concept prototype. Hard cap: 4 hours. If not demonstrable in 4 hours, the question is too large. Split it.
5. **Observe and decide** — no formal playtest debrief. Ask: "Did the spike answer the question? YES or NO, and why in one sentence."
6. **Write a spike note** (not a full report) to `prototypes/[concept-name]-spike-[date]/SPIKE-NOTE.md` — first ask once for this step and the next, naming both files: "May I write `prototypes/[concept-name]-spike-[date]/SPIKE-NOTE.md` and clear the spike from `production/session-state/active.md`?" The note holds:
- Question tested
- Result (YES it works / NO it doesn't / PARTIAL — needs more investigation)
- What to do next (add to current sprint — at `workflow: minimal`, the brief's build order — / investigate further / abandon the idea)
7. **Update `production/session-state/active.md`** to clear the spike and return to the current sprint state (at `workflow: minimal`, the story in progress).
**No CD gate. No phase gate. No PROCEED/PIVOT/KILL.** Spike results inform decisions; they don't make them. The developer decides whether to add the mechanic/approach to the sprint backlog (at `workflow: minimal`, to the brief's build order) based on what the spike revealed.
**Performance spike (special case):** If the game involves demanding rendering —
large open worlds, hundreds of simultaneous physics bodies, heavy particle systems,
complex shaders — run a performance spike before writing gameplay code to confirm
the target hardware can sustain the required framerate. This is distinct from other
spikes in two ways:
- The question is "can the engine render [scene X] at 60fps on [minimum spec hardware]?"
not "does this mechanic feel good?"
- The output is a benchmark number, not a feel verdict
- No gameplay logic is needed — just the maximum intended scene load (terrain, draw
calls, physics objects, particles) running at once
- Build time stays within the ~4-hour cap; the spike is setting up the rendering
load, not the game
- If the answer is NO at this scope, this is an architecture or scope constraint
that affects everything downstream — better to surface it now than during Sprint 8
---
+2
View File
@@ -303,6 +303,8 @@ After writing (if approved):
- If coverage drift detected: "Regression suite may be drifting. Consider
running `/regression-suite audit` at the next sprint boundary."
At `workflow: minimal`, which has no sprints, say "next story" for "next sprint" in the three lines above.
Verdict, first match wins:
- **NOT ASSESSED** — the Section 1 stop at `qa.level: minimal`: "Regression
suite not generated at qa.level minimal". Tests are not required at this
@@ -16,6 +16,8 @@ every file write follows `.claude/docs/automation-modes.md`
Resolved above — use as-is. No block → defaults in `.claude/docs/config-resolution.md`.
# Release Checklist
**Scope this checklist to the project.** Emitting every item for every platform
trains the reader to skip the list, which defeats the gate:
+11 -6
View File
@@ -9,6 +9,8 @@ model: sonnet
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow,qa.level`
# Retrospective
Every `AskUserQuestion` call follows `.claude/docs/automation-modes.md`
@@ -33,11 +35,10 @@ not a filled-in report.** Check first, and stop if the check fails.
**A verdict of `NOT ASSESSED` is a success.** It is the correct, useful answer to
"what does the data say?" when there is no data. The failure mode this prevents is
specific and has been observed in practice: report templates whose verdict
enum had no "could not run" state produced **false clean passes** — an asset audit
returning COMPLIANT on a project with no assets and no standards, and a
performance profile reporting ">99% headroom against a 16.67ms budget" with zero
profiler data and no budget ever set.
specific: a report whose verdict enum has no "could not run" state produces
**false clean passes** — an asset audit returning COMPLIANT on a project with no
assets and no standards, or a performance profile reporting ">99% headroom against
a 16.67ms budget" with zero profiler data and no budget ever set.
**Absence of evidence is never evidence of absence.** A scan that finds no
matches because there are no files to scan has not verified anything. Say which of
@@ -262,7 +263,11 @@ If no, stop here. Verdict: **BLOCKED** — user declined write.
## Phase 6: Next Steps
Use `AskUserQuestion`:
At `workflow: minimal` (resolved above), which has no sprints, skip this question:
point to the retrospective file and say its action items go into the brief's build
order.
Otherwise, use `AskUserQuestion`:
- Prompt: "Retrospective complete. The action items and velocity data are ready. Would you like to start sprint planning now with this data pre-loaded?"
- Options:
- `[A] Yes — open sprint planning with retro action items and velocity delta pre-populated`
+8 -653
View File
@@ -9,8 +9,6 @@ model: opus
!`bash "${CLAUDE_SKILL_DIR}/../../hooks/yaml-helper.sh" resolve_config --keys automation,workflow,system_overrides`
# Review All GDDs
This skill reads every system GDD simultaneously and performs two complementary
@@ -55,108 +53,7 @@ surfaced as advisory only. At `minimal`, this skill is not applicable (no GDDs).
## Phase 1: Load Everything
### Phase 1a — L0: Summary Scan (fast, low tokens)
Before reading any full document, use Grep to extract `## Summary` sections
from all GDD files:
```
Grep pattern="## Summary" glob="design/gdd/*.md" output_mode="content" -A 5
```
**Fail open on a missing Summary.** Establish the denominator: glob
`design/gdd/*.md` and count **N**. A scan matching fewer than N means those GDDs
predate `## Summary` — never treat an absent Summary as a system out of scope.
A zero-match scan means "no GDD carries a Summary yet", not "nothing to review".
This review is holistic and loads its in-scope GDDs regardless (see Phase 1c);
the Summary scan only builds the manifest and narrows `since-last-review`, it
never shrinks the review set.
Display a manifest to the user:
```
Found [N] GDDs. Summaries:
• combat.md — [summary text]
• inventory.md — [summary text]
...
```
For `since-last-review` mode, compute the scope deterministically instead of
reasoning through git history:
```
Bash: bash .claude/scripts/review-scope.sh
```
It prints `PRIOR_REVIEW:`, a `CHANGED:` list, and a `DEPS ...:` list of each
changed GDD's declared dependencies. Use those lists as the scope — the
dependency lines are already the "Key deps" expansion, so no second pass is
needed. If `PRIOR_REVIEW: NONE`, a full review is required; fall back to `full`
mode.
Show the user which GDDs are in scope based on summaries before doing any full
reads. Only proceed to L1 for the `CHANGED` set plus the GDDs named on the
`DEPS` lines.
### Phase 1b — Registry Pre-Load (fast baseline)
Before full-reading any GDD, check for the entity registry:
```
Read path="design/registry/entities.yaml"
```
If the registry exists and has entries, use it as a **pre-built conflict
baseline**: known entities, items, formulas, and constants with their
authoritative values and source GDDs. In Phase 2, grep GDDs for registered
names first — this is faster than reading all GDDs in full before knowing
what to look for.
If the registry is empty or absent: proceed without it. Note in the report:
"Entity registry is empty — consistency checks rely on full GDD reads only.
Run `/consistency-check` after this review to populate the registry."
### Phase 1c — L1/L2: Section Load
Read whole (small, and every part is used):
1. `design/gdd/game-concept.md` — game vision, core loop, MVP definition (or
`design/game-brief.md`, the one-page brief that replaces it at `rigor: minimal` —
pitch, core loop, MVP list)
2. `design/gdd/game-pillars.md` if it exists — design pillars and anti-pillars
3. `design/gdd/systems-index.md` — authoritative system list, layers, dependencies, status
Then, for **every in-scope system GDD**, load the sections this review actually
consumes — **not the whole file**:
```
Grep pattern="^## (Dependencies|Detailed Rules|Detailed Design|Formulas|Tuning Knobs|Acceptance Criteria|Player Fantasy)" glob="design/gdd/*.md" output_mode="content" -A 40
```
That list is not a guess — it is exactly the union the Parallel Execution
contract below already enumerates: Phase 2 needs Dependencies, Detailed
Design/Rules, Formulas, Tuning Knobs and Acceptance Criteria; Phase 3 needs
Player Fantasy and progression/reward structure. Overview is narrative restated
by the Summary this skill already scanned in Phase 1a, and Edge Cases feeds no
checklist item here (`/design-review` owns per-GDD completeness). Loading them
put content in three context windows — this one and both sub-agents' — that no
checklist item ever read.
Accept **either** `## Detailed Rules` or `## Detailed Design`; the design standard
and the GDD template disagree on the name and they denote the same section.
**Escalate to a full read of one GDD** when a scanned section cross-references
material outside itself, or when a GDD matched **zero** sections — that GDD
predates the template, and a zero-match there means "unstructured", not "empty".
Never let a zero-match silently drop a system: the scan narrows the *read*, it
never shrinks the *review set*.
Report: "Loaded [N] system GDDs covering [M] systems. Pillars: [list]. Anti-pillars: [list]."
If fewer than 2 system GDDs exist (count the files present; an empty one is handled under NOT ASSESSED in Phase 5, not here), stop:
> "Cross-GDD review requires at least 2 system GDDs. Write more GDDs first,
> then re-run `/review-all-gdds`."
---
**Read `references/1-load.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
### Parallel Execution
@@ -176,7 +73,7 @@ consistency and design-theory review is its domain.
Dependencies, Detailed Design/Rules, Formulas, Tuning Knobs and Acceptance
Criteria; Phase 3 (design theory) needs Player Fantasy, progression/reward
structure and the game pillars.
- The full TR registry contents if loaded in Phase 1b (paste the registry text, not just a file path)
- The full entity registry contents (`design/registry/entities.yaml`) if loaded in Phase 1b (paste the registry text, not just a file path)
- The specific checklist items assigned to that agent's phase (Phase 2 gets 2a–2f; Phase 3 gets 3a–3g)
- The engine name and version — `engine.name` and `engine.version` from `project.yaml`, resolving each field independently (if its key is absent or empty, use `.claude/docs/technical-preferences.md`) — plus `docs/engine-reference/[engine]/VERSION.md`
@@ -186,569 +83,27 @@ Do not rely on the subagent to re-read these files — it has its own context wi
## Phase 2: Cross-GDD Consistency
Work through every pair and group of GDDs to find contradictions and gaps.
### 2a: Dependency Bidirectionality
For every GDD's Dependencies section, check that every listed dependency is
reciprocal:
- If GDD-A lists "depends on GDD-B", check that GDD-B lists GDD-A as a dependent
- If GDD-A lists "depended on by GDD-C", check that GDD-C lists GDD-A as a dependency
- Flag any one-directional dependency as a consistency issue
```
⚠️ Dependency Asymmetry
[system-a].md lists: Depends On → [system-b].md
[system-b].md does NOT list [system-a].md as a dependent
→ One of these documents has a stale dependency section
```
### 2b: Rule Contradictions
For each game rule, mechanic, or constraint defined in any GDD, check whether
any other GDD defines a contradicting rule for the same situation:
Categories to scan:
- **Floor/ceiling rules**: Does any GDD define a minimum value for an output? Does any other say a different system can bypass that floor? These contradict.
- **Resource ownership**: If two GDDs both define how a shared resource accumulates or depletes, do they agree?
- **State transitions**: If GDD-A describes what happens when a character dies,
does GDD-B's description of the same event agree?
- **Timing**: If GDD-A says "X happens on the same frame", does GDD-B assume
it happens asynchronously?
- **Stacking rules**: If GDD-A says status effects stack, does GDD-B assume
they don't?
```
🔴 Rule Contradiction
[system-a].md: "Minimum [output] after reduction is [floor_value]"
[system-b].md: "[mechanic] bypasses [system-a]'s rules and can reduce [output] to 0"
→ These rules directly contradict. Which GDD is authoritative?
```
### 2c: Stale References
**Start from the `## Cross-References` table where a GDD has one.** That table is
the document's own declaration of what it depends on — `templates/game-design-document.md`
tells authors it is machine-checked here, and `/design-system` requires it
whenever Dependencies names another GDD. For each row, confirm the `Target GDD`
exists and the `Specific Element Referenced` is still present in it under that
name, with the declared `Nature` still accurate.
A table that is absent, or still holding the template's bracketed examples, is
itself reportable: say the GDD declares no cross-references and that the prose
scan below was the only check applied. Do not treat an absent table as "no
dependencies" — it far more often means the section was never authored.
**Then scan the prose regardless**, table or no table: a declared table catches
what the author remembered, and the scan below catches what they did not.
For every cross-document reference (GDD-A mentions a mechanic, value, or
system name from GDD-B), verify the referenced element still exists in GDD-B
with the same name and behaviour:
- If GDD-A says "combo multiplier from the combat system feeds into score", check
that the combat GDD actually defines a combo multiplier that outputs to score
- If GDD-A references "the progression curve defined in [system].md", check that
[system].md actually has that curve, not a different progression model
- If GDD-A was written before GDD-B and assumed a mechanic that GDD-B later
designed differently, flag GDD-A as containing a stale reference. Severity: a
reference to a mechanic or formula that **does not exist** is **Blocking** — the
architecture would inherit a rule nobody defined; one that exists but was
designed differently is a **Warning**, unless the difference changes a rule the
referencing GDD depends on (then Blocking)
- If the **target GDD is not written yet** (no file in `design/gdd/`): when
`systems-index.md` lists that system (e.g. `Status: Not Started`), it is a
**Warning** — a dependency on planned work, to re-check when that GDD is
written; when neither a GDD nor a systems-index entry exists for it, it is
**Blocking** — nothing will ever define it
```
🔴 Stale Reference
inventory.md (written first): "Item weight uses the encumbrance formula
from movement.md"
movement.md (written later): Defines no encumbrance formula — uses a flat
carry limit instead
→ inventory.md references a formula that doesn't exist — Blocking
```
### 2d: Data and Tuning Knob Ownership Conflicts
Two GDDs should not both claim to own the same data or tuning knob. Scan all
Tuning Knobs sections across all GDDs and flag duplicates:
```
⚠️ Ownership Conflict
[system-a].md Tuning Knobs: "[multiplier_name] — controls [output] scaling"
[system-b].md Tuning Knobs: "[multiplier_name] — scales [output] with [factor]"
→ Two GDDs define multipliers on the same output. Which owns the final value?
This will produce either a double-application bug or a design conflict.
```
### 2e: Formula Compatibility
For GDDs whose formulas are connected (output of one feeds input of another),
check that the output range of the upstream formula is within the expected
input range of the downstream formula:
- If [system-a].md outputs values between [min]–[max], and [system-b].md is
designed to receive values between [min2]–[max2], is the mismatch intentional?
- If an economy GDD expects resource acquisition in range X, and the
progression GDD generates it at range Y, the economy will be trivial or
inaccessible — is that intended?
Flag incompatibilities as CONCERNS (design judgment needed, not necessarily wrong):
```
⚠️ Formula Range Mismatch
[system-a].md: Max [output] = [value_a] (at max [condition])
[system-b].md: Base [input] = [value_b], max [input] = [value_c]
→ Late-[stage] [scenario] can resolve in a single [event].
Is this intentional? If not, either [system-a]'s ceiling or [system-b]'s ceiling needs adjustment.
```
### 2f: Acceptance Criteria Cross-Check
Scan Acceptance Criteria sections across all GDDs for contradictions:
- GDD-A criteria: "Player cannot die from a single hit"
- GDD-B criteria: "Boss attack deals 150% of player max health"
These acceptance criteria cannot both pass simultaneously.
---
**Read `references/2-consistency.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 3: Game Design Holism
Review all GDDs together through the lens of game design theory and player
psychology. These are issues that individual GDD reviews cannot catch because
they require seeing all systems at once.
### 3a: Progression Loop Competition
A game should have one dominant progression loop that players feel is "the
point" of the game, with supporting loops that feed into it. When multiple
systems compete equally as the primary progression driver, players don't know
what the game is about.
Scan all GDDs for systems that:
- Award the player's primary resource (XP, levels, prestige, unlocks)
- Define themselves as the "core" or "main" loop
- Have comparable depth and time investment to other systems doing the same
```
⚠️ Competing Progression Loops
combat.md: Awards XP, unlocks abilities, is described as "the core loop"
crafting.md: Awards XP, unlocks recipes, is described as "the primary activity"
exploration.md: Awards XP, unlocks map areas, described as "the main driver"
→ Three systems all claim to be the primary progression loop and all award
the same primary currency. Players will optimise one and ignore the others.
Consider: one primary loop with the others as support systems.
```
### 3b: Player Attention Budget
Count how many systems require active player attention simultaneously during
a typical session. Each actively-managed system costs attention:
- Active = player must make decisions about this system regularly during play
- Passive = system runs automatically, player sees results but doesn't manage it
More than 3-4 simultaneously active systems creates cognitive overload for most
players. Present the count and flag if it exceeds 4 concurrent active systems:
```
⚠️ Cognitive Load Risk
Simultaneously active systems during [core loop moment]:
1. [system-a].md — [decision type] (active)
2. [system-b].md — [resource management] (active)
3. [system-c].md — [tracking] (active)
4. [system-d].md — [item/action use] (active)
5. [system-e].md — [cooldown/timer management] (active)
6. [system-f].md — [coordination decisions] (active)
→ 6 simultaneously active systems during the core loop.
Research suggests 3-4 is the comfortable limit for most players.
Consider: which of these can be made passive or simplified?
```
### 3c: Dominant Strategy Detection
A dominant strategy makes other strategies irrelevant — players discover it,
use it exclusively, and find the rest of the game boring. Look for:
- **Resource monopolies**: One strategy generates a resource significantly
faster than all others
- **Risk-free power**: A strategy that is both high-reward and low-risk
(if high-risk strategies exist, they need proportionally higher reward)
- **No trade-offs**: An option that is superior in all dimensions to all others
- **Obvious optimal path**: If any progression choice is "clearly correct",
the others aren't real choices
```
⚠️ Potential Dominant Strategy
combat.md: Ranged attacks deal 80% of melee damage with no risk
combat.md: Melee attacks deal 100% damage but require close range
→ Unless melee has a significant compensating advantage (AOE, stagger,
resource regeneration), ranged is dominant — higher safety, only 20% less
damage. Consider what melee offers that ranged cannot.
```
### 3d: Economic Loop Analysis
Identify all resources across all GDDs (gold, XP, crafting materials, stamina,
health, mana, etc.). For each resource, map its **sources** (how players gain
it) and **sinks** (how players spend it).
Flag dangerous economic conditions:
| Condition | Sign | Risk |
|-----------|------|------|
| **Infinite source, no sink** | Resource accumulates indefinitely | Late game becomes trivially easy |
| **Sink, no source** | Resource drains to zero | System becomes unavailable |
| **Source >> Sink** | Surplus accumulates | Resource becomes meaningless |
| **Sink >> Source** | Constant scarcity | Frustration and gatekeeping |
| **Positive feedback loop** | More resource → easier to earn more | Runaway leader, snowball |
| **No catch-up** | Falling behind accelerates deficit | Unrecoverable states |
```
🔴 Economic Imbalance: Unbounded Positive Feedback
gold economy:
Sources: monster drops (scales with player power), merchant selling (unlimited)
Sinks: equipment purchase (one-time), ability upgrades (finite count)
→ After equipment and abilities are purchased, gold has no sink.
Infinite surplus. Gold becomes meaningless mid-game.
Add ongoing gold sinks (upkeep, consumables, cosmetics, gambling).
```
### 3e: Difficulty Curve Consistency
When multiple systems scale with player progression, they must scale in
compatible directions and at compatible rates. Mismatched scaling curves
create unintended difficulty spikes or trivialisations.
For each system that scales over time, extract:
- What scales (enemy health, player damage, resource cost, area size)
- How it scales (linear, exponential, stepped)
- When it scales (level, time, area)
Compare all scaling curves. Flag mismatches:
```
⚠️ Difficulty Curve Mismatch
combat.md: Enemy health scales exponentially with area (×2 per area)
progression.md: Player damage scales linearly with level (+10% per level)
→ By area 5, enemies have 32× base health; player deals ~1.5× base damage.
The gap widens indefinitely. Late areas will become inaccessibly difficult
unless the curves are reconciled.
```
### 3f: Pillar Alignment
Every system should clearly serve at least one design pillar. A system that
serves no pillar is "scope creep by design" — it's in the game but not in
service of what the game is trying to be.
For each GDD system, check its Player Fantasy section against the design pillars.
Flag any system whose stated fantasy doesn't map to any pillar:
```
⚠️ Pillar Drift
fishing-system.md: Player Fantasy — "peaceful, meditative activity"
Pillars: "Brutal Combat", "Tense Survival", "Emergent Stories"
→ The fishing system serves none of the three pillars. Either add a pillar
that covers it, redesign it to serve an existing pillar, or cut it.
```
Also check anti-pillars — flag any system that does what an anti-pillar
explicitly says the game will NOT do:
```
🔴 Anti-Pillar Violation
Anti-Pillar: "We will NOT have linear story progression — player defines their path"
main-quest.md: Defines a 12-chapter linear story with mandatory sequence
→ This system directly violates the defined anti-pillar.
```
### 3g: Player Fantasy Coherence
The player fantasies across all systems should be compatible — they should
reinforce a consistent identity for what the player IS in this game. Conflicting
player fantasies create identity confusion.
```
⚠️ Player Fantasy Conflict
combat.md: "You are a ruthless, precise warrior — every kill is earned"
dialogue.md: "You are a charismatic diplomat — violence is always avoidable"
exploration.md: "You are a reckless adventurer — diving in without a plan"
→ Three systems present incompatible identities. Players will feel the game
doesn't know what it wants them to be. Consider: do these fantasies serve
the same core identity from different angles, or do they genuinely conflict?
```
---
**Read `references/3-design-holism.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 4: Cross-System Scenario Walkthrough
Walk through the game from the player's perspective to find problems that only
appear at the interaction boundary between multiple systems — things static
analysis of individual GDDs cannot surface.
### 4a: Identify Key Multi-System Moments
Scan all GDDs and identify the 3–5 most important player-facing moments where
multiple systems activate simultaneously. Look specifically for:
- **Combat + Economy overlap**: killing enemies that drop resources, spending
resources during combat, death/respawn interacting with economy state
- **Progression + Difficulty overlap**: level-up triggering mid-fight, ability
unlocks changing combat viability, difficulty scaling at progression milestones
- **Narrative + Gameplay overlap**: dialogue choices locking/unlocking mechanics,
story beats interrupting resource loops, quest completion triggering system
state changes
- **3+ system chains**: any player action that triggers System A, which feeds
into System B, which triggers System C (these are highest-risk interaction paths)
List each identified scenario with a one-line description before proceeding.
### 4b: Walk Through Each Scenario
For each scenario, step through the sequence explicitly:
1. **Trigger** — what player action or game event starts this?
2. **Activation order** — which systems activate, in what sequence?
3. **Data flow** — what does each system output, and is that output a valid
input for the next system in the chain?
4. **Player experience** — what does the player see, hear, or feel at each step?
5. **Failure modes** — are there any of the following?
- **Race conditions**: two systems trying to modify the same state simultaneously
- **Feedback loops**: System A amplifies System B which re-amplifies System A
with no cap or dampener
- **Broken state transitions**: a system assumes a state that a previous
system may have changed (e.g., "player is alive" assumption after a combat
step that could have caused death)
- **Contradictory messaging**: player receives conflicting feedback from two
systems reacting to the same event (e.g., "success" sound + "failure" UI)
- **Compounding difficulty spikes**: two systems both scaling up at the same
progression point, multiplying the intended difficulty increase
- **Reward conflicts**: two systems both reacting to the same trigger with
rewards that together exceed the intended value (double-dipping)
- **Undefined behavior**: the GDDs don't specify what happens in this combined
state (neither system's rules cover it)
```
Example walkthrough:
Scenario: Player kills elite enemy at level-up threshold during active quest
Trigger: Player lands killing blow on elite enemy
→ combat.md: awards kill XP (100 pts)
→ progression.md: XP total crosses level threshold → triggers level-up
Output: new level, stat increases, ability unlock popup
→ quest.md: kill-count criterion met → triggers quest completion event
Output: quest reward XP (500 pts), completion fanfare
→ progression.md (again): quest XP added → triggers SECOND level-up in same frame
⚠️ Data flow issue: quest.md awards XP without checking if a level-up
is already in progress. progression.md has no guard against concurrent
level-up events. Undefined behavior: does the player level up once or twice?
Does the ability popup fire twice? Does the second level use the updated or
pre-update stat baseline?
```
### 4c: Flag Scenario Issues
For each problem found during the walkthrough, categorize severity:
- **BLOCKER**: undefined behavior, broken state transition, or contradictory
player messaging — the experience is broken or incoherent in this scenario
- **WARNING**: compounding spikes, feedback loops without caps, reward conflicts —
the experience works but produces unintended outcomes
- **INFO**: minor ordering ambiguity or messaging overlap — worth noting but
unlikely to cause player-visible problems
Add all findings to the output report under **"Cross-System Scenario Issues"**.
Each finding must cite: the scenario name, the specific systems involved, the
step where the issue occurs, and the nature of the failure mode.
---
**Read `references/4-scenarios.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 5: Output the Review Report
```
## Cross-GDD Review Report
Date: [date]
GDDs Reviewed: [N] of [M] present
Not read: [each GDD that could not be read or is present but empty, by file name — or "none"]
Systems Covered: [list]
---
### Consistency Issues
#### Blocking (must resolve before architecture begins)
🔴 [Issue title]
[What GDDs are involved, what the contradiction is, what needs to change]
#### Warnings (should resolve, but won't block)
⚠️ [Issue title]
[What GDDs are involved, what the concern is]
---
### Game Design Issues
#### Blocking
🔴 [Issue title]
[What the problem is, which GDDs are involved, design recommendation]
#### Warnings
⚠️ [Issue title]
[What the concern is, which GDDs are affected, recommendation]
---
### Cross-System Scenario Issues
Scenarios walked: [N]
[List scenario names]
#### Blockers
🔴 [Scenario name] — [Systems involved]
[Step where failure occurs, nature of the failure mode, what must be resolved]
#### Warnings
⚠️ [Scenario name] — [Systems involved]
[What the unintended outcome is, recommendation]
#### Info
ℹ️ [Scenario name] — [Systems involved]
[Minor ordering ambiguity or note]
---
### GDDs Flagged for Revision
| GDD | Reason | Type | Priority |
|-----|--------|------|----------|
| [system-a].md | Rule contradiction with [system-b].md | Consistency | Blocking |
| [system-b].md | Rule contradiction with [system-a].md | Consistency | Blocking |
| [system-c].md | Stale reference to nonexistent mechanic | Consistency | Blocking |
| [system-d].md | No pillar alignment | Design Theory | Warning |
---
### Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
PASS: No blocking issues and no warnings.
NOT ASSESSED: One or more review phases could not run — named below.
CONCERNS: Warnings present that should be resolved, but nothing blocking.
FAIL: One or more blocking issues must be resolved before architecture begins.
### If NOT ASSESSED — what could not be reviewed, and why:
[Name each phase that did not run and the input it needed, and each GDD that could not be read or is present but empty, by file name]
### If FAIL — required actions before re-running:
[Specific list of what must change in which GDD]
```
**`NOT ASSESSED` — a cross-review is only as wide as what it could read.** Rank:
**above PASS**, **below CONCERNS and FAIL**. This skill's whole value is
comparing systems *against each other*, so it is unusually easy for it to look
thorough while covering a fraction of the surface. Emit it when any of:
- **Fewer than two GDDs were readable.** Contradiction-hunting across one document
is not a cross-review; a clean result there means only that nothing was
compared. This is the single most important trigger in this skill.
- **A whole review phase did not run** — consistency, design theory, economy,
pillar drift. A parallel phase that returned nothing has to be distinguished
from one that returned no findings; if a spawned agent produced no report, that
phase is NOT ASSESSED, not clean — an agent can return a fluent sentence,
write nothing, and consume a phase.
- **The design pillars are undefined**, so pillar-drift has no reference to drift
from — the same shape as an accessibility gate with no committed tier.
- **A GDD is present but empty** (headings only, or all placeholders), **or
could not be read**. Present is not the same as reviewable, and a stub
contradicts nothing.
Report the covered set explicitly either way: `GDDs reviewed: [N] of [M] present`
(`[M]` counts the system GDDs present — the Phase 1c set, not `game-concept.md`,
`game-pillars.md`, `systems-index.md` or an earlier `gdd-cross-review-*.md`),
and the `Not read:` line naming every GDD that could not be read or is present but empty, whatever the
verdict — a FAIL found in the GDDs that were read does not make the unread ones
reviewed.
A cross-review that silently skipped half the systems is indistinguishable from
one that found them consistent.
---
**Read `references/5-report.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 6: Write Report and Flag GDDs
Use `AskUserQuestion` for write permission:
- Prompt: "May I write this review to `design/gdd/gdd-cross-review-[date].md`?"
- Options: `[A] Yes — write the report` / `[B] No — skip`
> **`[date]` here means ISO 8601 — `YYYY-MM-DD`, e.g.
> `gdd-cross-review-2026-08-19.md`. This is not a style preference.**
> `.claude/scripts/review-scope.sh` picks the prior review with
> `sort | tail -1`, so lexical order IS chronological order only for ISO dates.
> Written as `aug-19-2026` or `19-08-2026`, the wrong file is chosen as the
> baseline, the changed-set is computed from it, and GDDs modified since the
> real last review silently escape the next one. That is the same
> quiet-escape failure the three fixes documented at the top of that script
> exist to prevent.
If any GDDs are flagged for revision, use a second `AskUserQuestion`:
- Prompt: "Should I update the systems index to mark these GDDs as needing revision? ([list of flagged GDDs])"
- Options: `[A] Yes — update systems index` / `[B] No — leave as-is`
- If yes: update each flagged GDD's Status field in systems-index.md to "Needs Revision".
(Do NOT append parentheticals to the status value — other skills match "Needs Revision"
as an exact string and parentheticals break that match.)
### Session State Update
After writing the report (and updating systems index if approved), silently
append to `production/session-state/active.md`:
## Session Extract — /review-all-gdds [date]
- Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
- GDDs reviewed: [N of M present]
- Phases not run: [names, or "None"]
- Flagged for revision: [comma-separated list, or "None"]
- Blocking issues: [N — brief one-line descriptions, or "None"]
- Recommended next: [the Phase 7 handoff action, condensed to one line]
- Report: design/gdd/gdd-cross-review-[date].md ← only if user approved the write
- Report: (not written — user declined at [date]) ← only if user declined the write
Use the appropriate line based on the user's response to the write-permission widget in Phase 6.
If `active.md` does not exist, create it with this block as the initial content.
Confirm in conversation: "Session state updated."
---
**Read `references/6-write.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Phase 7: Handoff
After all file writes are complete, use `AskUserQuestion` for a closing widget.
Before building options, check project state:
- Are there any Warning-level items that are simple edits (flagged with "30-second edit", "brief addition", or similar)? → offer inline quick-fix option
- Are any GDDs in the "Flagged for Revision" table? → offer /design-review option for each
- Read systems-index.md for the next system with Status: Not Started → offer /design-system option
- Is the verdict PASS or CONCERNS? → offer /gate-check or /create-architecture
Build the option list dynamically — only include options that apply:
**Option pool:**
- `[_] Apply quick fix: [W-XX description] in [gdd-name].md — [effort estimate]` (one option per simple-edit warning; only for Warning-level, not Blocking)
- `[_] Run /design-review [flagged-gdd-path] — address flagged warnings` (one per flagged GDD, if any)
- `[_] Run /design-system [next-system] — next in design order` (always include, name the actual system)
- `[_] Run /create-architecture — begin architecture (verdict is PASS/CONCERNS)` (include only if the verdict is PASS or CONCERNS — never on FAIL or NOT ASSESSED)
- `[_] Run /gate-check — validate Systems Design phase gate` (include if verdict is PASS)
- `[_] Stop here`
Assign letters A, B, C… only to included options. Mark the most pipeline-advancing option as `(recommended)`.
In collaborative and guided modes, never end the skill with plain text — always
close with this widget. In autonomous mode, print the verdict and recommended
next step, then record via `log_decision` (no widget).
---
**Read `references/7-handoff.md` now and follow it** — this phase's steps are in that file, not here. Read it again if the conversation was compacted or resumed during this phase.
## Error Recovery Protocol
@@ -0,0 +1,115 @@
# /review-all-gdds — Phase 1: Load Everything
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 1: Load Everything
**In this file:**
- Phase 1a — L0: Summary Scan (fast, low tokens)
- Phase 1b — Registry Pre-Load (fast baseline)
- Phase 1c — L1/L2: Section Load
### Phase 1a — L0: Summary Scan (fast, low tokens)
Before reading any full document, use Grep to extract `## Summary` sections
from all GDD files:
```
Grep pattern="## Summary" glob="design/gdd/*.md" output_mode="content" -A 5
```
**Fail open on a missing Summary.** Establish the denominator: glob
`design/gdd/*.md` and count **N**. A scan matching fewer than N means those GDDs
predate `## Summary` — never treat an absent Summary as a system out of scope.
A zero-match scan means "no GDD carries a Summary yet", not "nothing to review".
This review is holistic and loads its in-scope GDDs regardless (see Phase 1c);
the Summary scan only builds the manifest and narrows `since-last-review`, it
never shrinks the review set.
Display a manifest to the user:
```
Found [N] GDDs. Summaries:
• combat.md — [summary text]
• inventory.md — [summary text]
...
```
For `since-last-review` mode, compute the scope deterministically instead of
reasoning through git history:
```
Bash: bash .claude/scripts/review-scope.sh
```
It prints `PRIOR_REVIEW:`, a `CHANGED:` list, and a `DEPS ...:` list of each
changed GDD's declared dependencies. Use those lists as the scope — the
dependency lines are already the "Key deps" expansion, so no second pass is
needed. If `PRIOR_REVIEW: NONE`, a full review is required; fall back to `full`
mode.
Show the user which GDDs are in scope based on summaries before doing any full
reads. Only proceed to L1 for the `CHANGED` set plus the GDDs named on the
`DEPS` lines.
### Phase 1b — Registry Pre-Load (fast baseline)
Before full-reading any GDD, check for the entity registry:
```
Read path="design/registry/entities.yaml"
```
If the registry exists and has entries, use it as a **pre-built conflict
baseline**: known entities, items, formulas, and constants with their
authoritative values and source GDDs. In Phase 2, grep GDDs for registered
names first — this is faster than reading all GDDs in full before knowing
what to look for.
If the registry is empty or absent: proceed without it. Note in the report:
"Entity registry is empty — consistency checks rely on full GDD reads only.
Run `/consistency-check` after this review to populate the registry."
### Phase 1c — L1/L2: Section Load
Read whole (small, and every part is used):
1. `design/gdd/game-concept.md` — game vision, core loop, MVP definition (or
`design/game-brief.md`, the one-page brief that replaces it at `rigor: minimal` —
pitch, core loop, MVP list)
2. `design/gdd/game-pillars.md` if it exists — design pillars and anti-pillars
3. `design/gdd/systems-index.md` — authoritative system list, layers, dependencies, status
Then, for **every in-scope system GDD**, load the sections this review actually
consumes — **not the whole file**:
```
Grep pattern="^## (Dependencies|Detailed Rules|Detailed Design|Formulas|Tuning Knobs|Acceptance Criteria|Player Fantasy)" glob="design/gdd/*.md" output_mode="content" -A 40
```
That list is not a guess — it is exactly the union the Parallel Execution
contract below already enumerates: Phase 2 needs Dependencies, Detailed
Design/Rules, Formulas, Tuning Knobs and Acceptance Criteria; Phase 3 needs
Player Fantasy and progression/reward structure. Overview is narrative restated
by the Summary this skill already scanned in Phase 1a, and Edge Cases feeds no
checklist item here (`/design-review` owns per-GDD completeness). Loading them
put content in three context windows — this one and both sub-agents' — that no
checklist item ever read.
Accept **either** `## Detailed Rules` or `## Detailed Design`; the design standard
and the GDD template disagree on the name and they denote the same section.
**Escalate to a full read of one GDD** when a scanned section cross-references
material outside itself, or when a GDD matched **zero** sections — that GDD
predates the template, and a zero-match there means "unstructured", not "empty".
Never let a zero-match silently drop a system: the scan narrows the *read*, it
never shrinks the *review set*.
Report: "Loaded [N] system GDDs covering [M] systems. Pillars: [list]. Anti-pillars: [list]."
If fewer than 2 system GDDs exist (count the files present; an empty one is handled under NOT ASSESSED in Phase 5, not here), stop:
> "Cross-GDD review requires at least 2 system GDDs. Write more GDDs first,
> then re-run `/review-all-gdds`."
---
@@ -0,0 +1,145 @@
# /review-all-gdds — Phase 2: Cross-GDD Consistency
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 2: Cross-GDD Consistency
**In this file:**
- 2a: Dependency Bidirectionality
- 2b: Rule Contradictions
- 2c: Stale References
- 2d: Data and Tuning Knob Ownership Conflicts
- 2e: Formula Compatibility
- 2f: Acceptance Criteria Cross-Check
Work through every pair and group of GDDs to find contradictions and gaps.
### 2a: Dependency Bidirectionality
For every GDD's Dependencies section, check that every listed dependency is
reciprocal:
- If GDD-A lists "depends on GDD-B", check that GDD-B lists GDD-A as a dependent
- If GDD-A lists "depended on by GDD-C", check that GDD-C lists GDD-A as a dependency
- Flag any one-directional dependency as a consistency issue
```
⚠️ Dependency Asymmetry
[system-a].md lists: Depends On → [system-b].md
[system-b].md does NOT list [system-a].md as a dependent
→ One of these documents has a stale dependency section
```
### 2b: Rule Contradictions
For each game rule, mechanic, or constraint defined in any GDD, check whether
any other GDD defines a contradicting rule for the same situation:
Categories to scan:
- **Floor/ceiling rules**: Does any GDD define a minimum value for an output? Does any other say a different system can bypass that floor? These contradict.
- **Resource ownership**: If two GDDs both define how a shared resource accumulates or depletes, do they agree?
- **State transitions**: If GDD-A describes what happens when a character dies,
does GDD-B's description of the same event agree?
- **Timing**: If GDD-A says "X happens on the same frame", does GDD-B assume
it happens asynchronously?
- **Stacking rules**: If GDD-A says status effects stack, does GDD-B assume
they don't?
```
🔴 Rule Contradiction
[system-a].md: "Minimum [output] after reduction is [floor_value]"
[system-b].md: "[mechanic] bypasses [system-a]'s rules and can reduce [output] to 0"
→ These rules directly contradict. Which GDD is authoritative?
```
### 2c: Stale References
**Start from the `## Cross-References` table where a GDD has one.** That table is
the document's own declaration of what it depends on — `templates/game-design-document.md`
tells authors it is machine-checked here, and `/design-system` requires it
whenever Dependencies names another GDD. For each row, confirm the `Target GDD`
exists and the `Specific Element Referenced` is still present in it under that
name, with the declared `Nature` still accurate.
A table that is absent, or still holding the template's bracketed examples, is
itself reportable: say the GDD declares no cross-references and that the prose
scan below was the only check applied. Do not treat an absent table as "no
dependencies" — it far more often means the section was never authored.
**Then scan the prose regardless**, table or no table: a declared table catches
what the author remembered, and the scan below catches what they did not.
For every cross-document reference (GDD-A mentions a mechanic, value, or
system name from GDD-B), verify the referenced element still exists in GDD-B
with the same name and behaviour:
- If GDD-A says "combo multiplier from the combat system feeds into score", check
that the combat GDD actually defines a combo multiplier that outputs to score
- If GDD-A references "the progression curve defined in [system].md", check that
[system].md actually has that curve, not a different progression model
- If GDD-A was written before GDD-B and assumed a mechanic that GDD-B later
designed differently, flag GDD-A as containing a stale reference. Severity: a
reference to a mechanic or formula that **does not exist** is **Blocking** — the
architecture would inherit a rule nobody defined; one that exists but was
designed differently is a **Warning**, unless the difference changes a rule the
referencing GDD depends on (then Blocking)
- If the **target GDD is not written yet** (no file in `design/gdd/`): when
`systems-index.md` lists that system (e.g. `Status: Not Started`), it is a
**Warning** — a dependency on planned work, to re-check when that GDD is
written; when neither a GDD nor a systems-index entry exists for it, it is
**Blocking** — nothing will ever define it
```
🔴 Stale Reference
inventory.md (written first): "Item weight uses the encumbrance formula
from movement.md"
movement.md (written later): Defines no encumbrance formula — uses a flat
carry limit instead
→ inventory.md references a formula that doesn't exist — Blocking
```
### 2d: Data and Tuning Knob Ownership Conflicts
Two GDDs should not both claim to own the same data or tuning knob. Scan all
Tuning Knobs sections across all GDDs and flag duplicates:
```
⚠️ Ownership Conflict
[system-a].md Tuning Knobs: "[multiplier_name] — controls [output] scaling"
[system-b].md Tuning Knobs: "[multiplier_name] — scales [output] with [factor]"
→ Two GDDs define multipliers on the same output. Which owns the final value?
This will produce either a double-application bug or a design conflict.
```
### 2e: Formula Compatibility
For GDDs whose formulas are connected (output of one feeds input of another),
check that the output range of the upstream formula is within the expected
input range of the downstream formula:
- If [system-a].md outputs values between [min]–[max], and [system-b].md is
designed to receive values between [min2]–[max2], is the mismatch intentional?
- If an economy GDD expects resource acquisition in range X, and the
progression GDD generates it at range Y, the economy will be trivial or
inaccessible — is that intended?
Flag incompatibilities as CONCERNS (design judgment needed, not necessarily wrong):
```
⚠️ Formula Range Mismatch
[system-a].md: Max [output] = [value_a] (at max [condition])
[system-b].md: Base [input] = [value_b], max [input] = [value_c]
→ Late-[stage] [scenario] can resolve in a single [event].
Is this intentional? If not, either [system-a]'s ceiling or [system-b]'s ceiling needs adjustment.
```
### 2f: Acceptance Criteria Cross-Check
Scan Acceptance Criteria sections across all GDDs for contradictions:
- GDD-A criteria: "Player cannot die from a single hit"
- GDD-B criteria: "Boss attack deals 150% of player max health"
These acceptance criteria cannot both pass simultaneously.
---
@@ -0,0 +1,183 @@
# /review-all-gdds — Phase 3: Game Design Holism
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 3: Game Design Holism
**In this file:**
- 3a: Progression Loop Competition
- 3b: Player Attention Budget
- 3c: Dominant Strategy Detection
- 3d: Economic Loop Analysis
- 3e: Difficulty Curve Consistency
- 3f: Pillar Alignment
- 3g: Player Fantasy Coherence
Review all GDDs together through the lens of game design theory and player
psychology. These are issues that individual GDD reviews cannot catch because
they require seeing all systems at once.
### 3a: Progression Loop Competition
A game should have one dominant progression loop that players feel is "the
point" of the game, with supporting loops that feed into it. When multiple
systems compete equally as the primary progression driver, players don't know
what the game is about.
Scan all GDDs for systems that:
- Award the player's primary resource (XP, levels, prestige, unlocks)
- Define themselves as the "core" or "main" loop
- Have comparable depth and time investment to other systems doing the same
```
⚠️ Competing Progression Loops
combat.md: Awards XP, unlocks abilities, is described as "the core loop"
crafting.md: Awards XP, unlocks recipes, is described as "the primary activity"
exploration.md: Awards XP, unlocks map areas, described as "the main driver"
→ Three systems all claim to be the primary progression loop and all award
the same primary currency. Players will optimise one and ignore the others.
Consider: one primary loop with the others as support systems.
```
### 3b: Player Attention Budget
Count how many systems require active player attention simultaneously during
a typical session. Each actively-managed system costs attention:
- Active = player must make decisions about this system regularly during play
- Passive = system runs automatically, player sees results but doesn't manage it
More than 3-4 simultaneously active systems creates cognitive overload for most
players. Present the count and flag if it exceeds 4 concurrent active systems:
```
⚠️ Cognitive Load Risk
Simultaneously active systems during [core loop moment]:
1. [system-a].md — [decision type] (active)
2. [system-b].md — [resource management] (active)
3. [system-c].md — [tracking] (active)
4. [system-d].md — [item/action use] (active)
5. [system-e].md — [cooldown/timer management] (active)
6. [system-f].md — [coordination decisions] (active)
→ 6 simultaneously active systems during the core loop.
Research suggests 3-4 is the comfortable limit for most players.
Consider: which of these can be made passive or simplified?
```
### 3c: Dominant Strategy Detection
A dominant strategy makes other strategies irrelevant — players discover it,
use it exclusively, and find the rest of the game boring. Look for:
- **Resource monopolies**: One strategy generates a resource significantly
faster than all others
- **Risk-free power**: A strategy that is both high-reward and low-risk
(if high-risk strategies exist, they need proportionally higher reward)
- **No trade-offs**: An option that is superior in all dimensions to all others
- **Obvious optimal path**: If any progression choice is "clearly correct",
the others aren't real choices
```
⚠️ Potential Dominant Strategy
combat.md: Ranged attacks deal 80% of melee damage with no risk
combat.md: Melee attacks deal 100% damage but require close range
→ Unless melee has a significant compensating advantage (AOE, stagger,
resource regeneration), ranged is dominant — higher safety, only 20% less
damage. Consider what melee offers that ranged cannot.
```
### 3d: Economic Loop Analysis
Identify all resources across all GDDs (gold, XP, crafting materials, stamina,
health, mana, etc.). For each resource, map its **sources** (how players gain
it) and **sinks** (how players spend it).
Flag dangerous economic conditions:
| Condition | Sign | Risk |
|-----------|------|------|
| **Infinite source, no sink** | Resource accumulates indefinitely | Late game becomes trivially easy |
| **Sink, no source** | Resource drains to zero | System becomes unavailable |
| **Source >> Sink** | Surplus accumulates | Resource becomes meaningless |
| **Sink >> Source** | Constant scarcity | Frustration and gatekeeping |
| **Positive feedback loop** | More resource → easier to earn more | Runaway leader, snowball |
| **No catch-up** | Falling behind accelerates deficit | Unrecoverable states |
```
🔴 Economic Imbalance: Unbounded Positive Feedback
gold economy:
Sources: monster drops (scales with player power), merchant selling (unlimited)
Sinks: equipment purchase (one-time), ability upgrades (finite count)
→ After equipment and abilities are purchased, gold has no sink.
Infinite surplus. Gold becomes meaningless mid-game.
Add ongoing gold sinks (upkeep, consumables, cosmetics, gambling).
```
### 3e: Difficulty Curve Consistency
When multiple systems scale with player progression, they must scale in
compatible directions and at compatible rates. Mismatched scaling curves
create unintended difficulty spikes or trivialisations.
For each system that scales over time, extract:
- What scales (enemy health, player damage, resource cost, area size)
- How it scales (linear, exponential, stepped)
- When it scales (level, time, area)
Compare all scaling curves. Flag mismatches:
```
⚠️ Difficulty Curve Mismatch
combat.md: Enemy health scales exponentially with area (×2 per area)
progression.md: Player damage scales linearly with level (+10% per level)
→ By area 5, enemies have 32× base health; player deals ~1.5× base damage.
The gap widens indefinitely. Late areas will become inaccessibly difficult
unless the curves are reconciled.
```
### 3f: Pillar Alignment
Every system should clearly serve at least one design pillar. A system that
serves no pillar is "scope creep by design" — it's in the game but not in
service of what the game is trying to be.
For each GDD system, check its Player Fantasy section against the design pillars.
Flag any system whose stated fantasy doesn't map to any pillar:
```
⚠️ Pillar Drift
fishing-system.md: Player Fantasy — "peaceful, meditative activity"
Pillars: "Brutal Combat", "Tense Survival", "Emergent Stories"
→ The fishing system serves none of the three pillars. Either add a pillar
that covers it, redesign it to serve an existing pillar, or cut it.
```
Also check anti-pillars — flag any system that does what an anti-pillar
explicitly says the game will NOT do:
```
🔴 Anti-Pillar Violation
Anti-Pillar: "We will NOT have linear story progression — player defines their path"
main-quest.md: Defines a 12-chapter linear story with mandatory sequence
→ This system directly violates the defined anti-pillar.
```
### 3g: Player Fantasy Coherence
The player fantasies across all systems should be compatible — they should
reinforce a consistent identity for what the player IS in this game. Conflicting
player fantasies create identity confusion.
```
⚠️ Player Fantasy Conflict
combat.md: "You are a ruthless, precise warrior — every kill is earned"
dialogue.md: "You are a charismatic diplomat — violence is always avoidable"
exploration.md: "You are a reckless adventurer — diving in without a plan"
→ Three systems present incompatible identities. Players will feel the game
doesn't know what it wants them to be. Consider: do these fantasies serve
the same core identity from different angles, or do they genuinely conflict?
```
---
@@ -0,0 +1,87 @@
# /review-all-gdds — Phase 4: Cross-System Scenario Walkthrough
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 4: Cross-System Scenario Walkthrough
Walk through the game from the player's perspective to find problems that only
appear at the interaction boundary between multiple systems — things static
analysis of individual GDDs cannot surface.
### 4a: Identify Key Multi-System Moments
Scan all GDDs and identify the 3–5 most important player-facing moments where
multiple systems activate simultaneously. Look specifically for:
- **Combat + Economy overlap**: killing enemies that drop resources, spending
resources during combat, death/respawn interacting with economy state
- **Progression + Difficulty overlap**: level-up triggering mid-fight, ability
unlocks changing combat viability, difficulty scaling at progression milestones
- **Narrative + Gameplay overlap**: dialogue choices locking/unlocking mechanics,
story beats interrupting resource loops, quest completion triggering system
state changes
- **3+ system chains**: any player action that triggers System A, which feeds
into System B, which triggers System C (these are highest-risk interaction paths)
List each identified scenario with a one-line description before proceeding.
### 4b: Walk Through Each Scenario
For each scenario, step through the sequence explicitly:
1. **Trigger** — what player action or game event starts this?
2. **Activation order** — which systems activate, in what sequence?
3. **Data flow** — what does each system output, and is that output a valid
input for the next system in the chain?
4. **Player experience** — what does the player see, hear, or feel at each step?
5. **Failure modes** — are there any of the following?
- **Race conditions**: two systems trying to modify the same state simultaneously
- **Feedback loops**: System A amplifies System B which re-amplifies System A
with no cap or dampener
- **Broken state transitions**: a system assumes a state that a previous
system may have changed (e.g., "player is alive" assumption after a combat
step that could have caused death)
- **Contradictory messaging**: player receives conflicting feedback from two
systems reacting to the same event (e.g., "success" sound + "failure" UI)
- **Compounding difficulty spikes**: two systems both scaling up at the same
progression point, multiplying the intended difficulty increase
- **Reward conflicts**: two systems both reacting to the same trigger with
rewards that together exceed the intended value (double-dipping)
- **Undefined behavior**: the GDDs don't specify what happens in this combined
state (neither system's rules cover it)
```
Example walkthrough:
Scenario: Player kills elite enemy at level-up threshold during active quest
Trigger: Player lands killing blow on elite enemy
→ combat.md: awards kill XP (100 pts)
→ progression.md: XP total crosses level threshold → triggers level-up
Output: new level, stat increases, ability unlock popup
→ quest.md: kill-count criterion met → triggers quest completion event
Output: quest reward XP (500 pts), completion fanfare
→ progression.md (again): quest XP added → triggers SECOND level-up in same frame
⚠️ Data flow issue: quest.md awards XP without checking if a level-up
is already in progress. progression.md has no guard against concurrent
level-up events. Undefined behavior: does the player level up once or twice?
Does the ability popup fire twice? Does the second level use the updated or
pre-update stat baseline?
```
### 4c: Flag Scenario Issues
For each problem found during the walkthrough, categorize severity:
- **BLOCKER**: undefined behavior, broken state transition, or contradictory
player messaging — the experience is broken or incoherent in this scenario
- **WARNING**: compounding spikes, feedback loops without caps, reward conflicts —
the experience works but produces unintended outcomes
- **INFO**: minor ordering ambiguity or messaging overlap — worth noting but
unlikely to cause player-visible problems
Add all findings to the output report under **"Cross-System Scenario Issues"**.
Each finding must cite: the scenario name, the specific systems involved, the
step where the issue occurs, and the nature of the failure mode.
---
@@ -0,0 +1,118 @@
# /review-all-gdds — Phase 5: Output the Review Report
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 5: Output the Review Report
**In this file:**
- The report template
- `NOT ASSESSED` and where it ranks
```
## Cross-GDD Review Report
Date: [date]
GDDs Reviewed: [N] of [M] present
Not read: [each GDD that could not be read or is present but empty, by file name — or "none"]
Systems Covered: [list]
---
### Consistency Issues
#### Blocking (must resolve before architecture begins)
🔴 [Issue title]
[What GDDs are involved, what the contradiction is, what needs to change]
#### Warnings (should resolve, but won't block)
⚠️ [Issue title]
[What GDDs are involved, what the concern is]
---
### Game Design Issues
#### Blocking
🔴 [Issue title]
[What the problem is, which GDDs are involved, design recommendation]
#### Warnings
⚠️ [Issue title]
[What the concern is, which GDDs are affected, recommendation]
---
### Cross-System Scenario Issues
Scenarios walked: [N]
[List scenario names]
#### Blockers
🔴 [Scenario name] — [Systems involved]
[Step where failure occurs, nature of the failure mode, what must be resolved]
#### Warnings
⚠️ [Scenario name] — [Systems involved]
[What the unintended outcome is, recommendation]
#### Info
ℹ️ [Scenario name] — [Systems involved]
[Minor ordering ambiguity or note]
---
### GDDs Flagged for Revision
| GDD | Reason | Type | Priority |
|-----|--------|------|----------|
| [system-a].md | Rule contradiction with [system-b].md | Consistency | Blocking |
| [system-b].md | Rule contradiction with [system-a].md | Consistency | Blocking |
| [system-c].md | Stale reference to nonexistent mechanic | Consistency | Blocking |
| [system-d].md | No pillar alignment | Design Theory | Warning |
---
### Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
PASS: No blocking issues and no warnings.
NOT ASSESSED: One or more review phases could not run — named below.
CONCERNS: Warnings present that should be resolved, but nothing blocking.
FAIL: One or more blocking issues must be resolved before architecture begins.
### If NOT ASSESSED — what could not be reviewed, and why:
[Name each phase that did not run and the input it needed, and each GDD that could not be read or is present but empty, by file name]
### If FAIL — required actions before re-running:
[Specific list of what must change in which GDD]
```
**`NOT ASSESSED` — a cross-review is only as wide as what it could read.** Rank:
**above PASS**, **below CONCERNS and FAIL**. This skill's whole value is
comparing systems *against each other*, so it is unusually easy for it to look
thorough while covering a fraction of the surface. Emit it when any of:
- **Fewer than two GDDs were readable.** Contradiction-hunting across one document
is not a cross-review; a clean result there means only that nothing was
compared. This is the single most important trigger in this skill.
- **A whole review phase did not run** — consistency, design theory, economy,
pillar drift. A parallel phase that returned nothing has to be distinguished
from one that returned no findings; if a spawned agent produced no report, that
phase is NOT ASSESSED, not clean — an agent can return a fluent sentence,
write nothing, and consume a phase.
- **The design pillars are undefined**, so pillar-drift has no reference to drift
from — the same shape as an accessibility gate with no committed tier.
- **A GDD is present but empty** (headings only, or all placeholders), **or
could not be read**. Present is not the same as reviewable, and a stub
contradicts nothing.
Report the covered set explicitly either way: `GDDs reviewed: [N] of [M] present`
(`[M]` counts the system GDDs present — the Phase 1c set, not `game-concept.md`,
`game-pillars.md`, `systems-index.md` or an earlier `gdd-cross-review-*.md`),
and the `Not read:` line naming every GDD that could not be read or is present but empty, whatever the
verdict — a FAIL found in the GDDs that were read does not make the unread ones
reviewed.
A cross-review that silently skipped half the systems is indistinguishable from
one that found them consistent.
---
@@ -0,0 +1,49 @@
# /review-all-gdds — Phase 6: Write Report and Flag GDDs
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 6: Write Report and Flag GDDs
Use `AskUserQuestion` for write permission:
- Prompt: "May I write this review to `design/gdd/gdd-cross-review-[date].md`?"
- Options: `[A] Yes — write the report` / `[B] No — skip`
> **`[date]` here means ISO 8601 — `YYYY-MM-DD`, e.g.
> `gdd-cross-review-2026-08-19.md`. This is not a style preference.**
> `.claude/scripts/review-scope.sh` picks the prior review with
> `sort | tail -1`, so lexical order IS chronological order only for ISO dates.
> Written as `aug-19-2026` or `19-08-2026`, the wrong file is chosen as the
> baseline, the changed-set is computed from it, and GDDs modified since the
> real last review silently escape the next one. That is the same
> quiet-escape failure the three fixes documented at the top of that script
> exist to prevent.
If any GDDs are flagged for revision, use a second `AskUserQuestion`:
- Prompt: "Should I update the systems index to mark these GDDs as needing revision? ([list of flagged GDDs])"
- Options: `[A] Yes — update systems index` / `[B] No — leave as-is`
- If yes: update each flagged GDD's Status field in systems-index.md to "Needs Revision".
(Do NOT append parentheticals to the status value — other skills match "Needs Revision"
as an exact string and parentheticals break that match.)
### Session State Update
After writing the report (and updating systems index if approved), silently
append to `production/session-state/active.md`:
## Session Extract — /review-all-gdds [date]
- Verdict: [PASS / NOT ASSESSED / CONCERNS / FAIL]
- GDDs reviewed: [N of M present]
- Phases not run: [names, or "None"]
- Flagged for revision: [comma-separated list, or "None"]
- Blocking issues: [N — brief one-line descriptions, or "None"]
- Recommended next: [the Phase 7 handoff action, condensed to one line]
- Report: design/gdd/gdd-cross-review-[date].md ← only if user approved the write
- Report: (not written — user declined at [date]) ← only if user declined the write
Use the appropriate line based on the user's response to the write-permission widget in Phase 6.
If `active.md` does not exist, create it with this block as the initial content.
Confirm in conversation: "Session state updated."
---
@@ -0,0 +1,32 @@
# /review-all-gdds — Phase 7: Handoff
> Part of `/review-all-gdds`. `SKILL.md` names when to read this file; the settings it
> resolved and the rules under its later headings still apply here.
## Phase 7: Handoff
After all file writes are complete, use `AskUserQuestion` for a closing widget.
Before building options, check project state:
- Are there any Warning-level items that are simple edits (flagged with "30-second edit", "brief addition", or similar)? → offer inline quick-fix option
- Are any GDDs in the "Flagged for Revision" table? → offer /design-review option for each
- Read systems-index.md for the next system with Status: Not Started → offer /design-system option
- Is the verdict PASS or CONCERNS? → offer /gate-check or /create-architecture
Build the option list dynamically — only include options that apply:
**Option pool:**
- `[_] Apply quick fix: [W-XX description] in [gdd-name].md — [effort estimate]` (one option per simple-edit warning; only for Warning-level, not Blocking)
- `[_] Run /design-review [flagged-gdd-path] — address flagged warnings` (one per flagged GDD, if any)
- `[_] Run /design-system [next-system] — next in design order` (always include, name the actual system)
- `[_] Run /create-architecture — begin architecture (verdict is PASS/CONCERNS)` (include only if the verdict is PASS or CONCERNS — never on FAIL or NOT ASSESSED)
- `[_] Run /gate-check — validate Systems Design phase gate` (include if verdict is PASS)
- `[_] Stop here`
Assign letters A, B, C… only to included options. Mark the most pipeline-advancing option as `(recommended)`.
In collaborative and guided modes, never end the skill with plain text — always
close with this widget. In autonomous mode, print the verdict and recommended
next step, then record via `log_decision` (no widget).
---

Some files were not shown because too many files have changed in this diff Show More