From 3f7c754239ff7474c1dc3ec0655859683d3a22fe Mon Sep 17 00:00:00 2001 From: Bastien Chanot Date: Sun, 19 Jul 2026 19:51:06 +0200 Subject: [PATCH] =?UTF-8?q?feat(routing):=20W1=20no-inherit=20=E2=80=94=20?= =?UTF-8?q?fable=20skill-runners,=20opus=20review=20dispatches,=20dispatch?= =?UTF-8?q?-tier=20doctrine=20(BDR-077)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit No dispatched agent inherits the session model anymore: - client-handover-writer's 7 general-purpose skill-runner dispatch sites carry model: "fable" (+ normative rule; spike-verified alias — resolves claude-fable-5, enum-validated, loud failure, never silent fallback) - ship-feature STEP 6 + init-project STEP 10 code-review dispatches carry model: "opus" (was: inherit — the leak the maps exposed) - model-gate.md §4: dispatch-tier doctrine (typed = frontmatter pin, built-ins = explicit model= at every call site) - census §12 (66 pass), make test green --- agents/client-handover-writer.md | 17 +++++++++++------ lib/model-gate.md | 10 ++++++++++ lib/tests/model-routing.test.sh | 9 +++++++++ skills/init-project/SKILL.md | 5 ++++- skills/ship-feature/SKILL.md | 5 ++++- 5 files changed, 38 insertions(+), 8 deletions(-) diff --git a/agents/client-handover-writer.md b/agents/client-handover-writer.md index 5e5af96..77f91f9 100644 --- a/agents/client-handover-writer.md +++ b/agents/client-handover-writer.md @@ -257,7 +257,12 @@ pipeline is reduced: only run /cso (single audit, single fix loop), skip STEP 6 deploy pause and STEP 7 /web-validate. Treat /cso as the only score for the gate. -For web projects, dispatch in **a single message with two parallel Agent calls**: +**Model routing (BDR-077):** EVERY `general-purpose` skill-runner dispatch in +this pipeline (initial audits, fix-loop re-dispatches, commit-change, +web-validate) carries `model: "fable"` — the child hosts gated orchestration +on the pipeline's behalf; it must never inherit the session model. + +For web projects, dispatch in **a single message with two parallel Agent calls** (each with `model: "fable"`): | Audit (web) | Subagent | Prompt template | |---------------|-------------------|-----------------| @@ -383,7 +388,7 @@ console). If no projected line is parseable, treat projected = 17 ### Re-dispatch prompt template (SEO + GEO loop) -Send to `general-purpose` subagent: +Send to `general-purpose` subagent (`model: "fable"`): > Read `~/.claude/skills/seo/SKILL.md` and re-run it on this project. > Previous scores: @@ -413,7 +418,7 @@ Send to `general-purpose` subagent: ### Re-dispatch prompt template (HARDEN loop) -Send to `general-purpose` subagent: +Send to `general-purpose` subagent (`model: "fable"`): > Read `~/.claude/skills/harden/SKILL.md` and re-run it. Previous score: > **``/20** — below threshold. Iteration `` of @@ -424,7 +429,7 @@ Send to `general-purpose` subagent: ### Re-dispatch prompt template (CSO loop — non-web only) -Send to `general-purpose` subagent: +Send to `general-purpose` subagent (`model: "fable"`): > Read `~/.claude/skills/cso/SKILL.md` and re-run it in **daily mode**. > Previous score: **``/20** — below threshold. @@ -510,7 +515,7 @@ listed changes manually before deploy." Continue to STEP 6. If `PENDING_CHANGES` non-empty → invoke /commit-change skill via subagent: -> Dispatch `general-purpose` subagent. Prompt: +> Dispatch `general-purpose` subagent (`model: "fable"`). Prompt: > > "Read `~/.claude/skills/commit-change/SKILL.md` and execute. All pending > changes were produced by the client-handover ship pipeline during the @@ -617,7 +622,7 @@ Skip if `VALIDATE_SKIPPED=true` or `PROJECT_TYPE != web` (in either case ensure `VALIDATE_SKIPPED=true` is set so the gate logic in STEP 8 treats VALIDATE as not-applicable rather than failed). -Dispatch `general-purpose` subagent: +Dispatch `general-purpose` subagent (`model: "fable"`): > Read `~/.claude/skills/web-validate/SKILL.md` and execute against the > deployed URL: ``. Audit W3C HTML validity (validator.nu), diff --git a/lib/model-gate.md b/lib/model-gate.md index 56b4b06..97aab7b 100644 --- a/lib/model-gate.md +++ b/lib/model-gate.md @@ -35,3 +35,13 @@ yet rewritten) — that is why the self-check exists alongside it. then end the turn. No later step runs, no agent is dispatched, nothing is edited. + +## 4. Dispatch tiers (BDR-077 — no inherit) + +The gate guards the MAIN loop only. Dispatched work NEVER inherits the +session model: typed agents run on their frontmatter pin; built-ins +(general-purpose / Explore / Plan) carry an explicit `model=` at every call +site — `model: "fable"` when the child performs reflection/orchestration on +the main loop's behalf (skill-runners), otherwise its complexity tier +(opus = dispatched judgment, sonnet = execution/collection, haiku = short +mechanical probes). diff --git a/lib/tests/model-routing.test.sh b/lib/tests/model-routing.test.sh index 8b1b724..96b3ba6 100755 --- a/lib/tests/model-routing.test.sh +++ b/lib/tests/model-routing.test.sh @@ -72,6 +72,15 @@ fm_lacks "agents/interviewer.md" 'model:' has "skills/onboard/SKILL.md" 'model="opus"' has "skills/tour/SKILL.md" 'model="opus"' has "lib/challenge-plan.md" 'BDR-076' +# 12) BDR-077 W1 — no-inherit: skill-runner children pinned fable at every +# call site; code-review dispatches carry opus; doctrine in model-gate. +# (fable dispatch alias spike-verified 2026-07-19: resolves +# claude-fable-5, enum-validated, loud failure — never silent fallback) +has "agents/client-handover-writer.md" 'model: "fable"' +has "skills/ship-feature/SKILL.md" 'model: "opus"' +has "skills/init-project/SKILL.md" 'model: "opus"' +has "lib/model-gate.md" 'model: "fable"' +lacks "lib/model-gate.md" 'model: "sonnet" in the Agent call' printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail" [ "$fail" -eq 0 ] diff --git a/skills/init-project/SKILL.md b/skills/init-project/SKILL.md index 9d0ad71..fbab873 100644 --- a/skills/init-project/SKILL.md +++ b/skills/init-project/SKILL.md @@ -223,7 +223,10 @@ against the founding contract. Distinct axis from STEP 10 code review ([[LRN-095]]) — both run. ## STEP 10 — CODE REVIEW -Invoke `superpowers:requesting-code-review`. Fix all CRITICAL before proceeding. +Invoke `superpowers:requesting-code-review`. **Model routing (BDR-077):** the +review subagent it dispatches MUST carry `model: "opus"` in the Agent call — +craft review is dispatched judgment, never inherited from the session. Fix +all CRITICAL before proceeding. ## STEP 10b — CAPITALIZE FOUNDING DECISIONS (memory registries) A greenfield's founding architecture decisions are the highest-value BDRs — the diff --git a/skills/ship-feature/SKILL.md b/skills/ship-feature/SKILL.md index 2d59962..907d581 100644 --- a/skills/ship-feature/SKILL.md +++ b/skills/ship-feature/SKILL.md @@ -222,7 +222,10 @@ conformity + security vs. craft/design) — both run, neither subsumes the other ([[LRN-095]]). ## STEP 6 — CODE REVIEW -Invoke `superpowers:requesting-code-review`. Fix all CRITICAL before proceeding. +Invoke `superpowers:requesting-code-review`. **Model routing (BDR-077):** the +review subagent it dispatches MUST carry `model: "opus"` in the Agent call — +craft review is dispatched judgment, never inherited from the session. Fix +all CRITICAL before proceeding. ## STEP 7 — CAPITALIZE (memory registries) Feature shipped implies at least one design decision worth capturing. Run this BEFORE STEP 9 FINISH — the implementation commits (STEP 4) already exist, so the entries' hash references are valid, and the memory commit lands on the branch that FINISH integrates (otherwise it strands outside the PR):