Release 1.1.2 — the default path works end to end

Fix release for 1.1.1: the minimal path end to end, engine commands that
run on Godot, Unity and Unreal, hook warnings you can see, and verdicts
that say when they could not check. Details in CHANGELOG.md; upgrade
steps in UPGRADING.md (v1.1.1 → v1.1.2).

Fixes #67
Fixes #131

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
This commit is contained in:
Donchitos
2026-09-29 21:32:19 +10:00
co-authored by Claude Opus 5.5
parent 7ed2c3e9c4
commit b21fa0f7f2
383 changed files with 22888 additions and 10618 deletions
@@ -2,196 +2,258 @@
## Skill Summary
`/architecture-decision` guides the user through section-by-section authoring of
a new Architecture Decision Record (ADR). Required sections are: Status, Context,
Decision, Consequences, Alternatives, and Related ADRs. The skill also stamps the
engine version reference from `docs/engine-reference/` into the ADR for traceability.
`/architecture-decision` authors one Architecture Decision Record (ADR). It has
three entry modes: normal authoring (`/architecture-decision [title]`),
`retrofit <path>` (adds missing sections to an existing ADR without touching the
rest), and `accept <ADR-id>` (the only path that moves an ADR from `Proposed` to
`Accepted`). When retrofit asks for a missing Status and the user answers
`Accepted`, it writes `Proposed` and hands the ADR to acceptance mode.
In `full` review mode, TD-ADR (technical-director) and LP-FEASIBILITY
(lead-programmer) gate agents spawn after the draft is complete. If both gates
return APPROVED, the ADR status is set to Accepted. In `lean` or `solo` mode,
both gates are skipped and the ADR is written with Status: Proposed. The skill
asks "May I write" per section during authoring. ADRs are written to
`docs/architecture/adr-NNN-[name].md`.
Normal authoring loads engine context first (`docs/engine-reference/[engine]/VERSION.md`,
plus a knowledge-gap warning for MEDIUM/HIGH-risk domains), picks the next ADR
number, checks `docs/registry/architecture.yaml` for binding stances, then
presents its assumptions as a confirm/adjust `AskUserQuestion` (Status is always
`Proposed` and is never asked). It then drafts the whole ADR from its template in
one pass, has the primary engine specialist validate it (Step 5.5), runs the
TD-ADR gate in `full` review mode only (Step 5.6), runs a GDD sync check that
always reports, and asks once — "May I write it?" — before writing
`docs/architecture/adr-[NNNN]-[slug].md`. A separate approval covers the registry
update. The closing output tells the user to run `/architecture-review` in a
fresh session and `/architecture-decision accept ADR-NNNN` when the decision is
settled. Authoring never sets `Accepted` and never unblocks stories.
---
## Static Assertions (Structural)
Verified automatically by `/skill-test static` — no fixture needed.
Checked against the SKILL.md by `/skill-test spec` — no fixture needed.
- [ ] Has required frontmatter fields: `name`, `description`, `argument-hint`, `user-invocable`, `allowed-tools`
- [ ] Has ≥2 phase headings
- [ ] Contains verdict keywords: ACCEPTED, PROPOSED, CONCERNS
- [ ] Contains "May I write" collaborative protocol language (per-section approval)
- [ ] Has a next-step handoff at the end
- [ ] Documents gate behavior: TD-ADR + LP-FEASIBILITY in full mode; skipped in lean/solo
- [ ] Documents that ADR status is Accepted (full, gates approve) or Proposed (otherwise)
- [ ] Mentions engine version stamp from `docs/engine-reference/`
- [ ] Contains status/verdict keywords: `Proposed`, `Accepted`, and the TD-ADR outcomes `CONCERNS` / `REJECT`
- [ ] Contains "May I write" collaborative protocol language (whole-ADR write approval and registry approval)
- [ ] Has a next-step handoff at the end (`/architecture-review`, `accept ADR-NNNN`)
- [ ] Documents gate behavior: engine specialist validation, then TD-ADR in full mode; TD-ADR skipped in lean/solo with a named note
- [ ] Documents that authoring always produces `Proposed` and only acceptance mode sets `Accepted` — retrofit's `Accepted` answer is routed through it
- [ ] Mentions the engine version stamp from `docs/engine-reference/` (Engine Compatibility table)
---
## Director Gate Checks
In `full` mode: TD-ADR (technical-director) and LP-FEASIBILITY (lead-programmer)
spawn after the ADR draft is complete. If both return APPROVED, ADR Status is set
to Accepted. If either returns CONCERNS or FAIL, ADR stays Proposed.
Review mode comes from the resolved `review_mode` (`modes.review_mode` in
`project.yaml`); `--review full|lean|solo` overrides it for one run.
In `lean` mode: both gates are skipped. ADR is written with Status: Proposed.
Output notes: "TD-ADR skipped — lean mode" and "LP-FEASIBILITY skipped — lean mode".
In `full` mode: after the draft is generated, the primary engine specialist
validates it (Step 5.5), then `technical-director` spawns with gate TD-ADR
(Step 5.6). The two run in that order, not in parallel. On CONCERNS the
concerns are shown verbatim and the user picks `Revise flagged items` /
`Accept and proceed` / `Discuss further`; on REJECT the draft is revised before
the write approval. No verdict changes the ADR's Status.
In `solo` mode: both gates are skipped. ADR is written with Status: Proposed.
In `lean` mode: TD-ADR is skipped (it is not a PHASE-GATE). Output notes
"TD-ADR skipped — Lean mode." The engine specialist validation still runs.
In `solo` mode: TD-ADR is skipped. Output notes "TD-ADR skipped — Solo mode."
The engine specialist validation still runs.
In every mode the written ADR has `Status: Proposed`.
---
## Test Cases
### Case 1: Happy Path — New ADR for rendering approach, full mode, gates approve
### Case 1: Happy Path — New rendering ADR, full mode, TD-ADR approves
**Fixture:**
- `docs/architecture/` exists with no existing ADR for rendering
- `docs/engine-reference/[engine]/VERSION.md` exists
- `production/session-state/review-mode.txt` contains `full`
- `project.yaml` has `engine.name: Godot` and `modes.review_mode: full`
- `docs/engine-reference/godot/VERSION.md` exists and marks the pinned version HIGH risk; `breaking-changes.md` lists a Rendering change
- `docs/architecture/` contains `adr-0001-*.md` and `adr-0002-*.md`; none covers rendering
- `docs/registry/architecture.yaml` exists with no stance touching rendering
- `design/gdd/visual-effects.md` exists; the user confirms it as the GDD driving the decision, and its names match the ADR's Key Interfaces
- The engine specialist finds only minor notes; TD-ADR returns APPROVE
**Input:** `/architecture-decision rendering-approach`
**Expected behavior:**
1. Skill guides user through each required section (Status, Context, Decision, Consequences, Alternatives, Related ADRs)
2. Engine version is stamped into the ADR from `docs/engine-reference/`
3. For each section: draft shown, "May I write this section?" asked, approved
4. After all sections: TD-ADR and LP-FEASIBILITY gates spawn in parallel
5. Both gates return APPROVED
6. ADR Status is set to Accepted
7. Skill writes `docs/architecture/adr-NNN-rendering-approach.md`
8. `docs/architecture/tr-registry.yaml` updated if new TR-IDs are defined
1. Step 1 reads `VERSION.md` first and displays the ENGINE KNOWLEDGE GAP WARNING for the Rendering domain
2. Step 2 scans `docs/architecture/` and assigns ADR-0003
3. Step 3a reads the registry before any existing ADR
4. Step 4 presents assumptions (problem, 2–3 alternatives, GDD linkage, dependencies, `Status: Proposed`) as a confirm/adjust `AskUserQuestion`; no ADR is generated until the user confirms
5. Step 5 drafts the full template, including the Engine Compatibility table (engine, domain, knowledge risk, references consulted)
6. `godot-specialist` validates the draft; minor notes go into the Risks section
7. `technical-director` then spawns with gate TD-ADR and returns APPROVE
8. GDD sync check prints `GDD sync: checked 1 referenced GDD(s), no naming inconsistencies.` — never silent
9. "ADR draft is complete. May I write it?" — on yes, writes `docs/architecture/adr-0003-rendering-approach.md` with `Status: Proposed`
10. Registry candidates are shown and "May I update `docs/registry/architecture.yaml` with these [N] new stances?" is asked separately
11. Closing output includes the fixed notice to run `/architecture-review` in a fresh session, and "Run `/architecture-decision accept ADR-0003` when the decision is settled"
**Assertions:**
- [ ] All 6 required sections are authored and written
- [ ] Engine version reference is stamped in the ADR
- [ ] TD-ADR and LP-FEASIBILITY spawn in parallel (not sequentially)
- [ ] ADR Status is Accepted when both gates return APPROVED in full mode
- [ ] "May I write" is asked per section during authoring
- [ ] File is written to `docs/architecture/adr-NNN-[name].md`
- [ ] `VERSION.md` is read before any other step, and the knowledge-gap warning is shown for the HIGH-risk domain
- [ ] Assumptions are confirmed via `AskUserQuestion` before the ADR is generated; Status is shown as `Proposed`, never asked
- [ ] The engine specialist validation runs before TD-ADR (sequential, not parallel)
- [ ] One "May I write" approval covers the whole ADR; the file is `docs/architecture/adr-0003-rendering-approach.md`
- [ ] The written ADR has `Status: Proposed` even though TD-ADR returned APPROVE
- [ ] The GDD sync check reports the clean result for `visual-effects.md` in one line
- [ ] The registry update has its own approval prompt, separate from the ADR write
- [ ] Closing output contains the fresh-session `/architecture-review` notice and the `accept ADR-0003` command
---
### Case 2: Failure Path — TD-ADR returns CONCERNS
**Fixture:**
- ADR draft is complete (all sections filled)
- `production/session-state/review-mode.txt` contains `full`
- TD-ADR gate returns CONCERNS: "The decision does not address [specific concern]"
- Same as Case 1, but TD-ADR returns CONCERNS: "Alternatives do not address the mobile renderer"
- One point stays unresolved after revision (which renderer to target on mobile)
**Input:** `/architecture-decision [topic]`
**Input:** `/architecture-decision rendering-approach`
**Expected behavior:**
1. TD-ADR gate spawns and returns CONCERNS with specific feedback
2. Skill surfaces the concerns to the user
3. ADR Status remains Proposed (not Accepted)
4. User is asked: revise the decision to address concerns, or accept as Proposed
5. ADR is written with Status: Proposed if concerns are not resolved
1. TD-ADR spawns with the draft, engine version, domain and related ADRs
2. The CONCERNS are shown to the user verbatim with the standard options from `director-gates.md`: `Revise flagged items` / `Accept and proceed` / `Discuss further`
3. The user picks `Revise flagged items`; only then are the Decision or Alternatives sections revised (Step 5.6)
4. The unresolved point is presented as its own `AskUserQuestion` with options from the review plus "Different approach — I'll describe it"
5. The write approval is still asked; nothing is written before it
6. The ADR is written with `Status: Proposed`
**Assertions:**
- [ ] TD-ADR concerns are shown to the user verbatim
- [ ] ADR Status is Proposed (not Accepted) when TD-ADR returns CONCERNS
- [ ] Skill does NOT set Status: Accepted while CONCERNS are unresolved
- [ ] User is given the option to revise and re-run the gate
- [ ] TD-ADR receives the ADR draft/path, engine version and domain as context
- [ ] The CONCERNS are shown verbatim and the user chooses Revise / Accept / Discuss — the draft is not revised before that choice
- [ ] Each unresolved decision is a separate `AskUserQuestion` with a free-text escape option
- [ ] The ADR is written only after the "May I write" approval, with `Status: Proposed`
---
### Case 3: Lean Mode — Both gates skipped; ADR written as Proposed
### Case 3: Lean and Solo Modes — TD-ADR skipped; checks that cannot run say so
**Fixture:**
- `production/session-state/review-mode.txt` contains `lean`
- ADR draft is authored for a new technical decision
- Scenario (a): `project.yaml` has `modes.review_mode: lean` and `engine.name: Godot`
- Scenario (b): same project, invoked with `--review solo`
- Scenario (c): invoked with `--review solo` on a project with no engine configured — `engine.name` unset and `.claude/docs/technical-preferences.md` still `[TO BE CONFIGURED]`; at Step 1's prompt the user carries on without running `/setup-engine`
- `design/gdd/` holds no GDD, so the ADR's GDD Requirements Addressed names none
**Input:** `/architecture-decision [topic]`
**Input:** (a) `/architecture-decision save-format` (b) and (c) `/architecture-decision save-format --review solo`
**Expected behavior:**
1. Skill guides user through all 6 sections
2. After draft is complete: both TD-ADR and LP-FEASIBILITY are skipped
3. Output notes: "TD-ADR skipped — lean mode" and "LP-FEASIBILITY skipped — lean mode"
4. ADR is written with Status: Proposed (not Accepted, since gates did not approve)
5. "May I write" is still asked before the final file write
1. (a) and (b): the engine specialist validation (Step 5.5) runs
2. (a) Output notes "TD-ADR skipped — Lean mode." and proceeds to the GDD sync check
3. (b) and (c): Output notes "TD-ADR skipped — Solo mode." and proceeds to the GDD sync check
4. (c) No engine specialist is spawned, and the output records `Engine validation: NOT ASSESSED — no engine configured (engine.name unset in project.yaml)`
5. The GDD sync check prints `GDD sync: NOT ASSESSED — [the ADR names no GDDs]`, not the clean one-line result
6. "May I write it?" is still asked before the file is written
7. The ADR is written with `Status: Proposed`
**Assertions:**
- [ ] Both gate skip notes appear in output
- [ ] ADR Status is Proposed (not Accepted) in lean mode
- [ ] "May I write" is still asked before writing the file
- [ ] Skill writes the ADR after user approval
- [ ] `technical-director` is not spawned in lean or solo mode
- [ ] The skip note names the gate and the mode ("TD-ADR skipped — Lean mode." / "— Solo mode.")
- [ ] The `--review solo` argument overrides the resolved `review_mode` for the run
- [ ] (a) and (b): the engine specialist validation still runs
- [ ] (c) With no engine configured, the output says engine validation was NOT ASSESSED instead of passing silently
- [ ] With no GDD named, the GDD sync check reports NOT ASSESSED, not a clean result
- [ ] "May I write" is asked before the file is written, and Status is `Proposed`
---
### Case 4: Edge Case — ADR already exists for this topic
### Case 4: Edge Case — Proposed decision contradicts a registered stance
**Fixture:**
- `docs/architecture/` contains an existing ADR covering the same topic
- The existing ADR has Status: Accepted
- `docs/registry/architecture.yaml` records an interface contract: `damage_delivery → signal pattern (ADR-0003)`
- ADR-0003 is Accepted
- The user states the proposal when invoking the skill, before Step 1: the decision is to deliver damage by direct method calls
**Input:** `/architecture-decision [same-topic]`
**Input:** `/architecture-decision damage-pipeline`, with that description in the same message
**Expected behavior:**
1. Skill detects an existing ADR covering the same topic
2. Skill asks: "An ADR for [topic] already exists ([filename]). Update it, or create a new superseding ADR?"
3. User selects update or supersede
4. Skill does NOT silently create a duplicate ADR
1. Step 3a reads the registry before opening any existing ADR, and presents the relevant stances as locked constraints under "Existing Architectural Stances (must not contradict)"
2. Still in Step 3a — right after the stances, before Step 4's assumptions prompt — the skill surfaces the conflict: "⚠️ Conflict: This ADR proposes [X], but ADR-0003 established that [Y]…"
3. It offers three options: (1) align with the existing stance, (2) supersede ADR-0003 with an explicit replacement, (3) explain why this case is an exception
4. It does not proceed to Step 4 until the conflict is resolved or accepted as an intentional exception
5. If the user chooses to supersede: at the registry step the old entry is set to `status: superseded_by: ADR-[NNNN]` and the new entry is added — the existing entry is not otherwise modified
**Assertions:**
- [ ] Skill detects the existing ADR before authoring begins
- [ ] User is offered update or supersede options — no silent duplicate
- [ ] If update: skill opens the existing ADR for section-by-section revision
- [ ] If supersede: new ADR references the superseded one in Related ADRs section
- [ ] The registry is read before any existing ADR file
- [ ] The conflict warning names ADR-0003 and offers exactly the three options above
- [ ] The confirm/adjust assumptions prompt (Step 4) does not appear until the conflict is resolved
- [ ] On supersede, the old registry entry is marked `superseded_by`, not edited or deleted
---
### Case 5: Director Gate — Status set correctly based on mode and gate outcome
### Case 5: Acceptance Mode — Status moves to Accepted only through `accept`
**Fixture:**
- ADR draft is complete
- Two scenarios: (a) full mode, both gates APPROVED; (b) full mode, one gate CONCERNS
- `docs/architecture/adr-0005-physics-layers.md` exists with `Status: Proposed`
- Scenario (a): its `## ADR Dependencies` lists `Depends On: ADR-0002`, and ADR-0002 is `Proposed`
- Scenario (b): its only dependency is ADR-0001, which is `Accepted`; three files under `production/epics/*/story-*.md` name `ADR-0005` and are Blocked — two in the header form `/create-stories` writes (`> **Status**: Blocked`), one as `**Status:** Blocked`
- `modes.automation` is `autonomous`
**Full mode, both APPROVED:**
- ADR Status is set to Accepted
**Input:** `/architecture-decision accept ADR-0005`
**Assertions (both approved):**
- [ ] ADR frontmatter/header shows `Status: Accepted`
- [ ] Both TD-ADR and LP-FEASIBILITY appear as APPROVED in output
**Expected behavior:**
1. The skill globs `docs/architecture/adr-0005-*.md` and reads the single match
2. (a) It refuses and names the blocker: ADR-0005 depends on ADR-0002, which is still Proposed; no file is edited
3. (b) It finds the stories to unblock before asking, then asks "Accept ADR-0005 — [title]? …" with the count ("3 stories become Ready"), options `[A] Yes — accept it` / `[B] Not yet — leave it Proposed`
4. (b) The prompt fires even though automation is `autonomous`
5. (b) On yes: edits `## Status` to `Accepted`, leaves an existing `## Date` unchanged (adding one only if absent), moves the three stories from `Blocked` to `Ready`, and reports the ADR and each story that moved
**Full mode, one gate returns CONCERNS:**
- ADR Status stays Proposed
**Assertions:**
- [ ] (a) Acceptance is refused when a dependency is not `Accepted`, naming ADR-0002; nothing is written
- [ ] (b) The confirmation prompt states how many stories will become Ready
- [ ] (b) The confirmation prompt appears in `autonomous` automation mode
- [ ] (b) Status becomes `Accepted` and the three stories move to `Ready` only after the user confirms
- [ ] Stories are matched only under `production/epics/`
- [ ] (b) All three stories are found — the Blocked grep matches `> **Status**: Blocked` and `**Status:** Blocked`, not only the literal `Status: Blocked`
**Assertions (CONCERNS):**
- [ ] ADR frontmatter/header shows `Status: Proposed`
- [ ] Concerns are listed in output
- [ ] Skill does NOT set Status: Accepted when any gate returns CONCERNS
---
**Lean/solo mode:**
- ADR Status is always Proposed regardless of content quality
### Case 6: Retrofit — Missing Status answered `Accepted`
**Assertions (lean/solo):**
- [ ] ADR Status is Proposed in lean mode
- [ ] ADR Status is Proposed in solo mode
- [ ] No gate output appears in lean or solo mode
**Fixture:**
- `docs/architecture/adr-0004-input-mapping.md` exists with Context, Decision, Consequences, Engine Compatibility and GDD Requirements Addressed, but no `## Status` and no `## ADR Dependencies`
- ADR-0001 is `Accepted`
- One file under `production/epics/*/story-*.md` names `ADR-0004` and has `> **Status**: Blocked`
**Input:** `/architecture-decision retrofit docs/architecture/adr-0004-input-mapping.md`
**Expected behavior:**
1. The retrofit block lists Status (BLOCKING), ADR Dependencies (HIGH) and Date (MEDIUM — the fixture has no `## Date` and no `## Last Verified`) as missing, then asks "Shall I add the 3 missing sections? I will not modify any existing content."
2. Asked for the current status, the user answers "Accepted" — the decision is already in force; asked for dependencies, the user answers "Depends On: ADR-0001"
3. The skill appends `## Status` as `Proposed`, the ADR Dependencies section and `## Date` (today, noted as the retrofit date); no existing section changes
4. It then runs acceptance mode on ADR-0004: the dependency check passes (ADR-0001 is Accepted), the blocked story is found, and "Accept ADR-0004 — [title]? …" is asked with "1 story becomes Ready"
5. On yes: `## Status` becomes `Accepted`, the `## Date` the retrofit added is kept, and the story moves from `Blocked` to `Ready`
**Assertions:**
- [ ] Only the missing sections are appended; existing sections are untouched
- [ ] The retrofit answer `Accepted` is never written straight into `## Status`; `Accepted` appears only after acceptance mode's dependency check and confirmation
- [ ] The confirmation prompt names the story count, as in Case 5
- [ ] Variant — the user declines "Shall I add the 3 missing sections?": no section is written, `## Date` included
---
## Protocol Compliance
- [ ] All 6 required sections authored before gate review
- [ ] Engine version stamped in ADR from `docs/engine-reference/`
- [ ] "May I write" asked per section during authoring
- [ ] TD-ADR and LP-FEASIBILITY spawn in parallel in full mode
- [ ] Skipped gates noted by name and mode in lean/solo output
- [ ] ADR Status: Accepted only when full mode AND both gates APPROVED
- [ ] Ends with next-step handoff: `/architecture-review` or `/create-control-manifest`
- [ ] Engine context (`VERSION.md`) is loaded first and stamped into the Engine Compatibility table
- [ ] Assumptions are confirmed via `AskUserQuestion` before the ADR is generated
- [ ] "May I write" is asked once for the whole ADR before writing; the registry update has its own approval
- [ ] TD-ADR runs only in full mode; lean/solo print a skip note naming the gate and mode
- [ ] TD-ADR CONCERNS are shown verbatim with `Revise flagged items` / `Accept and proceed` / `Discuss further`, never revised without the user's choice
- [ ] A TD-ADR `NOT ASSESSED` answer names the missing input and is never presented as an approval
- [ ] Authoring always writes `Status: Proposed`; `Accepted` is set only by acceptance mode after its dependency check and explicit user confirmation — directly through `accept`, or when retrofit hands it an `Accepted` answer
- [ ] Engine validation and the GDD sync check each report `NOT ASSESSED` when they cannot run, never a silent pass
- [ ] Authoring does not unblock stories; it lists the stories still waiting on the ADR
- [ ] Ends with next-step handoff: `/architecture-review` in a fresh session, and `/architecture-decision accept ADR-NNNN`
---
## Coverage Notes
- ADR numbering (auto-incrementing NNN) is not independently fixture-tested —
the skill reads existing ADR filenames to assign the next number.
- Related ADRs section linking (supersedes / related-to) is tested structurally
via Case 4 but not all link types are individually verified.
- The TR-registry update (when new TR-IDs are defined in the ADR) is part of the
write phase — tested implicitly via Case 1.
- Retrofit is fixture-tested only for a missing Status answered `Accepted`
(Case 6); the other answers (`Proposed`, `Deprecated`, `Superseded`) and the
retrofit of Engine Compatibility and GDD Requirements Addressed are not.
- The acceptance-mode refusals for a missing `## Status`, an absent or `UNKNOWN`
dependency section, and an already-Accepted or Superseded ADR are not
individually fixture-tested.
- Of the GDD sync check's three outcomes, the one-line clean result (Case 1)
and `NOT ASSESSED` (Case 3) are tested; the warning block and its
three-option write approval are not.
- `team.size` and `docs.density` variations are not tested.
- ADR numbering is not independently fixture-tested beyond Case 1.