Release 1.1.0 — one config file, and a process weight you choose

`project.yaml` at the repo root is now the single source of truth for a
project's configuration, replacing `production/stage.txt`,
`production/review-mode.txt` and `.claude/docs/technical-preferences.md` (all
three still read as a fallback; nothing is force-deleted).

**`modes.rigor` — one question instead of six.** `minimal`, `standard` or
`full` fronts six knobs: `modes.workflow`, `docs.density`, `qa.level`,
`modes.story_granularity`, `modes.review_mode` and `team.size`. It defaults to
`minimal`, which is a change from 1.0's behaviour: the heavier tier was
measured costing several times more to reach working code without producing a
better result, and returning nothing when a fresh developer inherited the
project. Pin `modes.rigor: standard` to keep 1.0's process level.

Also in this release:

- `/settings` to view or change any setting, and `project.local.yaml` for
  per-developer preferences that should not be committed.
- `system_overrides` to hold one system to a higher standard than the rest of
  the project, and `testing.strict` to set per test type whether missing
  evidence blocks a story or warns.
- A story that changes anything the player sees is not closed until the game
  has been launched, observed, and a screenshot retained in
  `production/qa/evidence/`. A parse check is not a run. This holds at every
  rigor level, including `minimal`, where automated tests are waived but the
  look is not.
- The code root is engine-specific and enforced as such: Godot `src/`, Unity
  `Assets/`, Unreal `Source/<Module>/`. Two of the three will not build a
  project laid out any other way.
- Migration tooling for existing projects: `.claude/scripts/migrate-v1-config.sh`
  converts a 1.0 layout, non-destructively by default, with a report to review
  before `--finalize` deletes anything.
- Ask-before-write holds regardless of personal automation settings.

Upgrading from 1.0 or earlier: see UPGRADING.md. Full list of changes:
CHANGELOG.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016xvzG3i7pWQg4LjyDwWMXd
This commit is contained in:
Donchitos
2026-09-23 12:25:11 +10:00
co-authored by Claude Opus 5
parent 984023ddac
commit d05699707f
291 changed files with 24374 additions and 7740 deletions
@@ -0,0 +1,94 @@
# /architecture-decision — Handoff Contract
## Role in Pipeline
Authors a new Architecture Decision Record (ADR) by guiding a collaborative design session, cross-referencing the engine reference library and existing architectural stances, and writing a fully-structured ADR file to `docs/architecture/` — which then unblocks stories and epics that depend on the decision.
Two checks inside the run emit `NOT ASSESSED` rather than passing silently, and
a reader of the resulting ADR should expect them: **engine validation** when no
engine is configured (`engine.name` unset and no legacy fallback), and **GDD
sync** when the referenced design docs cannot be read. A skipped check that says
nothing is indistinguishable from a check that passed.
## Inputs Required
### Files That Must Exist
| File | Required Fields / Sections | Read-Only? |
|------|---------------------------|-----------|
| `docs/engine-reference/[engine]/VERSION.md` | Engine name + version, LLM knowledge cutoff date, post-cutoff risk levels per domain | Yes |
| `docs/engine-reference/[engine]/modules/[domain].md` | Domain-specific API reference (read if exists for the decision's domain) | Yes |
| `docs/engine-reference/[engine]/breaking-changes.md` | Post-cutoff breaking changes in the relevant domain | Yes |
| `docs/engine-reference/[engine]/deprecated-apis.md` | APIs that must not be referenced in the new ADR | Yes |
| `docs/registry/architecture.yaml` | All existing architectural stances (state ownership, interface contracts, forbidden patterns, performance budgets) — checked for conflicts before the design begins | Yes |
| `docs/architecture/` (existing ADRs) | Scanned to determine the next sequential ADR number | Yes |
| `design/gdd/[system].md` (GDDs relevant to the decision) | Specific rules, formulas, performance constraints, or integration points that motivate the decision | Yes |
| `project.yaml` | `engine.name` — derives the primary specialist (`<engine>-specialist`) to spawn for validation (Step 4.5) | Yes |
| `.claude/docs/technical-preferences.md` | `Engine Specialists` section — legacy fallback, used only when `engine.name` is absent or empty in `project.yaml` | Yes — required only when `engine.name` is absent |
### Preconditions
- An engine must be configured (`docs/engine-reference/[engine]/VERSION.md` must exist) — if not, the skill prompts to run `/setup-engine` first
- The title or subject of the decision must be provided by the user before Step 0 proceeds (if no argument is given, the skill asks)
- If in **retrofit mode** (`retrofit [path]` argument), the target ADR file must already exist on disk
- Any conflict with a registered architectural stance in `docs/registry/architecture.yaml` must be resolved or explicitly accepted as an exception before the ADR is drafted (Step 2a is a BLOCKING gate)
## Outputs Produced
### Files Written
| File | Guaranteed Fields / Sections | Notes |
|------|------------------------------|-------|
| `docs/architecture/adr-NNNN-[slug].md` | `## Status`, `## Date`, `## Engine Compatibility` (table with engine, domain, knowledge risk, post-cutoff APIs, verification required), `## ADR Dependencies` (table with depends-on, enables, blocks, ordering note), `## Context` (problem statement, constraints, requirements), `## Decision` (+ architecture diagram + key interfaces), `## Alternatives Considered`, `## Consequences` (positive, negative, risks), `## GDD Requirements Addressed` (table), `## Performance Implications`, `## Migration Plan`, `## Validation Criteria`, `## Related Decisions` | created after user approves ("May I write this ADR to docs/architecture/adr-NNNN-[slug].md?") |
| `docs/registry/architecture.yaml` | New stance entries (state ownership, interface contracts, performance budgets, forbidden patterns) derived from the ADR; existing entries marked `status: superseded_by` if overridden | appended after separate user approval ("May I update docs/registry/architecture.yaml with these N new stances?") |
### Output Guarantees
- The ADR number is the next sequential integer after the highest existing `adr-NNNN-*` filename in `docs/architecture/`
- `## Status` is always present and set to `Proposed` unless the user explicitly confirms `Accepted` during the session
- `## Engine Compatibility` is always populated using verified data from the engine reference docs — never from training data alone when the domain carries MEDIUM or HIGH risk
- `## GDD Requirements Addressed` is always present (if no GDD motivated the decision, it documents which GDDs the decision will constrain or enable)
- `## ADR Dependencies` is always present (fields set to "None" if no ordering constraints exist)
- Engine specialist validation (Step 4.5) runs before the file is written if an engine specialist is configured; blocking issues found by the specialist cause the Decision section to be revised before saving
## Immutability Rules
- READS but does NOT modify: all existing ADR files in `docs/architecture/` (including in retrofit mode — existing sections are never touched), all GDD files in `design/gdd/`, `docs/engine-reference/**`, `project.yaml`, `.claude/docs/technical-preferences.md` (legacy fallback)
- MODIFIES: `docs/architecture/adr-NNNN-[slug].md` (new file created; or missing sections appended in retrofit mode), `docs/registry/architecture.yaml` (append only; existing entries get `status: superseded_by` annotation, never deleted or rewritten)
- In retrofit mode: appends only the missing sections — never modifies any section that is already present in the target ADR file
## Hard Constraints (Never Violate)
- Never sets `Status: Accepted` without explicit user confirmation — the default on creation is always `Status: Proposed`
- **Acceptance route: `/architecture-decision accept ADR-NNNN`** — the only path that sets `Accepted`. It refuses when a dependency is still Proposed, and prompts for confirmation regardless of `modes.automation`. Without this route acceptance would be enforced by ten skills, owned per the authority below, and reachable by nobody.
- **Acceptance authority: the user, or `technical-director` on the user's explicit confirmation — no other agent, and not this skill on its own.** Recorded here because every consumer enforces the consequences of acceptance, and without this line nothing would say who can produce it. This narrows *who* may set the field; it does not relax the confirmation rule above.
- Never assigns an ADR number that is already in use — always scan `docs/architecture/` first and use the next sequential number
- Never proceeds past the architectural stance conflict check (Step 2a) if a conflict exists — surface the conflict and require resolution or explicit exception acknowledgment before drafting
- Never references APIs listed in `docs/engine-reference/[engine]/deprecated-apis.md` in the Decision or Key Interfaces sections
- Never writes the ADR file without asking: "May I write this ADR to docs/architecture/adr-NNNN-[slug].md?"
- Never writes to `docs/registry/architecture.yaml` without a separate ask: "May I update docs/registry/architecture.yaml with these N new stances?"
- In retrofit mode: never modifies any existing section — only appends absent sections
## Downstream Skill Expects
**Next skills:** `/create-epics`, `/create-stories`, `/dev-story`, `/architecture-review`
### `/create-epics` reads ADRs expecting:
- `## Status` field — value must be `Accepted` for epics to reference it
- `## GDD Requirements Addressed` table — used to link epics to GDD traceability
- `## Engine Compatibility` section — checked during the Technical Setup → Pre-Production gate
### `/create-stories` reads ADRs expecting:
- `## Implementation Guidelines` section — provides the concrete patterns programmer agents must follow (note: this section is generated during `/create-stories`, not by `/architecture-decision` itself; the ADR must have a Decision section detailed enough to derive these guidelines)
- `## ADR Dependencies` table — stories referencing a `Depends On` ADR that is still `Proposed` are automatically set `Status: Blocked`
### `/dev-story` reads ADRs expecting:
- `## Decision` (full text, verbatim — not summarized)
- `## Implementation Guidelines` (verbatim)
- `## Engine Compatibility` (post-cutoff API risks, verification required)
- `## ADR Dependencies` (to detect if this ADR's dependencies are unresolved)
### `/architecture-review` reads ADRs expecting:
- All required sections present (it flags gaps)
- `## Status` is set (required for coverage matrix)
- `## Engine Compatibility` is stamped with the correct engine version
## Known Fragile Points
- If the ADR number scan misses a file (e.g., a file in a subdirectory of `docs/architecture/` or with a non-standard naming pattern), a duplicate number can be assigned — all ADR files must follow the `adr-NNNN-[slug].md` naming convention at the top level of `docs/architecture/`
- Stories that were `Status: Blocked` pending this ADR must be manually updated to `Status: Ready` after the ADR reaches `Accepted` — the skill surfaces a reminder but does not automatically update story files
- The `## GDD Requirements Addressed` table is populated based on what the user tells the skill during the collaborative session; if the user does not know which GDDs motivated the decision, this table may be incomplete — `/create-epics` and `/gate-check` both rely on this linkage for traceability
- Engine specialist validation (Step 4.5) is skipped only when **both** sources are unset — `engine.name` absent or empty in `project.yaml` **and** `.claude/docs/technical-preferences.md` still reading `[TO BE CONFIGURED]`. A project configured solely via `project.yaml` **does** get specialist validation. When both are unset, post-cutoff engine API risks are not caught before the ADR is written
- `docs/registry/architecture.yaml` is append-only by design; if a stance entry becomes permanently invalid (not superseded by another ADR), it must be manually removed — there is no cleanup mechanism
- In retrofit mode, if the existing ADR has sections present but empty (e.g., a `## Status` heading with no value), the skill treats the section as present and does not fill it — an empty Status is effectively invisible to downstream skills like `/story-readiness`
+203 -23
View File
@@ -1,22 +1,50 @@
---
name: architecture-decision
description: "Creates an Architecture Decision Record (ADR) documenting a significant technical decision, its context, alternatives considered, and consequences. Every major technical choice should have an ADR."
argument-hint: "[title] [--review full|lean|solo]"
description: "Create an ADR documenting a technical decision: context, alternatives considered, consequences."
argument-hint: "[title | retrofit <path> | accept <ADR-id>] [--review full|lean|solo]"
user-invocable: true
allowed-tools: Read, Glob, Grep, Write, Edit, Task, AskUserQuestion
allowed-tools: Read, Glob, Grep, Write, Edit, Agent, AskUserQuestion
model: sonnet
---
!`source "${CLAUDE_PROJECT_DIR:-.}/.claude/hooks/yaml-helper.sh" 2>/dev/null && resolve_config --keys review_mode,automation,workflow,docs.density,team.size`
Resolved above — use as-is; `--review` overrides `review_mode`. No block →
defaults in `.claude/docs/config-resolution.md`.
When this skill is invoked:
## 0. Parse Arguments — Detect Retrofit Mode
## 0. Parse Arguments — Detect Retrofit / Acceptance Mode
Resolve the review mode (once, store for all gate spawns this run):
1. If `--review [full|lean|solo]` was passed → use that
2. Else read `production/review-mode.txt` → use that value
3. Else → default to `lean`
See `.claude/docs/director-gates.md` for the full check pattern.
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).
**`team.size`**: which agents validate this ADR (orthogonal to review_mode/workflow).
- **`individual`** (default): `technical-director` + `lead-programmer` + the engine-specialist.
- **`small`**: + an engine sub-specialist where applicable.
- **`studio`**: + an adversarial review by an alternate engine-specialist.
Any non-core agent needed at `individual` routes through the nearest active core agent with a note.
**`docs.density`** — it controls the *depth* of the ADR's prose sections, not
which sections the skeleton emits (that is fixed). `modes.rigor` sets it
alongside `workflow`; set `docs.density` explicitly to vary ADR verbosity alone:
`terse` = decision + alternatives as bullets, one line of rationale each;
`balanced` = paragraph per section with light rationale (default); `thorough` =
full prose with trade-offs and worked rationale in Decision, Alternatives, and
Consequences. Apply it to the prose sections; the Engine Compatibility, ADR
Dependencies, and GDD Requirements tables are structural and stay whole at every
density.
**`workflow`** (see `.claude/docs/workflow-modes.md`):
- `full` — all ADRs on the required ADR list must be completed.
- `standard` — critical ADRs only (Foundation-layer systems).
- `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`):
@@ -59,7 +87,74 @@ Enter **retrofit mode**:
7. Suggest: "Run `/architecture-review` to re-validate coverage now that this ADR
has its Status and Dependencies fields."
If NOT in retrofit mode, proceed to Step 1 below (normal ADR authoring).
**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
`production/epics/[epic-slug]/story-*.md` — the one place stories live — for
files containing **both** `Status: Blocked` and this ADR's id.
> **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. That pairing is what "blocked pending this
ADR" means — a story blocked for an unrelated reason will not name it. 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`. Set the date in the
ADR's `## Date` section; **if that section is absent, add it** — 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, its new date, and every story that became Ready.
If NOT in retrofit or acceptance mode, proceed to Step 1 below (normal ADR authoring).
**No-argument guard**: If no argument was provided (title is empty), ask before
running Phase 0:
@@ -123,12 +218,13 @@ Scan `docs/architecture/` for existing ADRs to find the next number.
## 3. Gather context
Read related code, existing ADRs, and relevant GDDs from `design/gdd/`.
### 3a: Architecture Registry Check (BLOCKING gate)
### 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:
@@ -164,6 +260,34 @@ the conflict immediately:
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 (measured elsewhere in this project).
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.
---
## 4. Guide the decision collaboratively
@@ -175,7 +299,16 @@ 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; assume None if unclear
- **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
@@ -239,6 +372,20 @@ Following this format:
## 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 |
@@ -286,6 +433,11 @@ to implement it.]
### 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]
@@ -308,7 +460,7 @@ to implement it.]
### Negative
- [Trade-offs and costs accepted]
### Risks
## Risks
- [Things that could go wrong]
- [Mitigation for each risk]
@@ -330,14 +482,14 @@ to implement it.]
## Validation Criteria
[How will we know this decision was correct? What metrics or tests?]
## Related Decisions
- [Links to related ADRs]
## 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 Task to validate the drafted ADR:
- Read `.claude/docs/technical-preferences.md` `Engine Specialists` section to get the primary specialist
- If no engine is configured (`[TO BE CONFIGURED]`), skip this step
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
@@ -350,7 +502,7 @@ to implement it.]
- `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 Task using gate **TD-ADR** (`.claude/docs/director-gates.md`):
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
- If CONCERNS or REJECT: revise the Decision or Alternatives sections accordingly before proceeding
@@ -370,7 +522,21 @@ The GDD must be updated before or alongside writing this ADR to prevent
developers reading the GDD from implementing the wrong interface.
```
If no inconsistencies: skip this block silently.
**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`:
@@ -453,4 +619,18 @@ If there are no remaining priority ADRs and no undesigned GDD systems, offer onl
> The reviewing agent must be independent of the authoring context to give an unbiased
> assessment. Running it here would invalidate the review.
Update any stories that were `Status: Blocked` pending this ADR to `Status: Ready`.
**Do NOT unblock stories here.** This ADR is `Proposed` — Step 5 guarantees it,
and a story blocked *pending this decision* is still pending it. Unblocking on
authoring is how the deadlock stayed invisible: it defeated the guard at the
moment the guard became relevant, so the pipeline appeared to flow while running
on decisions nobody had accepted.
Instead, tell the user what is now waiting on acceptance:
> "ADR-NNNN is written and `Proposed`. [N] stories remain `Blocked` pending it.
> Run `/architecture-decision accept ADR-NNNN` when the decision is settled —
> that is what moves them to `Ready`."
List the blocked stories by path so the cost of leaving it Proposed is visible.
(Acceptance has consequences enforced across many skills and an authority
recorded in only a few, so the route between them must stay explicit.)