Merge bugfix/model-routing-edge-fixes into develop

This commit is contained in:
Bastien Chanot
2026-07-16 12:50:01 +02:00
7 changed files with 71 additions and 13 deletions
+2
View File
@@ -388,3 +388,5 @@ rules:
- model routing WAVE 3 (same branch): /bugfix + /code-clean split like /feat — reflection inline, sonnet executors (bugfixer, code-cleaner). code-clean refactor now runs on sonnet (inline-load pin was inert). consumers rerouted (hotfix deeper-bug→/bugfix skill; onboard/tour read-only audit→big-model agent). Explore kept built-in (inherits big). census 42/0, loops-light 35/0. Branch still unmerged. - model routing WAVE 3 (same branch): /bugfix + /code-clean split like /feat — reflection inline, sonnet executors (bugfixer, code-cleaner). code-clean refactor now runs on sonnet (inline-load pin was inert). consumers rerouted (hotfix deeper-bug→/bugfix skill; onboard/tour read-only audit→big-model agent). Explore kept built-in (inherits big). census 42/0, loops-light 35/0. Branch still unmerged.
- model routing waves 1-3 MERGED into develop (e5c7c51); LRN-125 added. WAVE 4 started on feature/client-handover-dispatch (off develop): client-handover doc-gen → sonnet. REDACTION-ONLY (user flipped from whole-writer — nested audits must run big either way). client-handover-writer trimmed to ship pipeline (STEP 1-8 preserved byte-for-byte) + delegates writing to NEW sonnet handover-doc-writer (gate-free, STEP 9-16). client-handover joins gated group. census 46/0. NOTE: a Task-20 implementer ran `git checkout -- settings.json`, discarding user /model=opus working-tree state (LRN-098) — flagged to user (re-run /model). Lesson worth an LRN: constrain SDD implementers from git ops on files outside their task. - model routing waves 1-3 MERGED into develop (e5c7c51); LRN-125 added. WAVE 4 started on feature/client-handover-dispatch (off develop): client-handover doc-gen → sonnet. REDACTION-ONLY (user flipped from whole-writer — nested audits must run big either way). client-handover-writer trimmed to ship pipeline (STEP 1-8 preserved byte-for-byte) + delegates writing to NEW sonnet handover-doc-writer (gate-free, STEP 9-16). client-handover joins gated group. census 46/0. NOTE: a Task-20 implementer ran `git checkout -- settings.json`, discarding user /model=opus working-tree state (LRN-098) — flagged to user (re-run /model). Lesson worth an LRN: constrain SDD implementers from git ops on files outside their task.
- wave-4 FINAL REVIEW (opus whole-branch): all 7 deliverable invariants hold, child gate-free, PACKAGE complete. Found 3 real regressions from the split — FIXED inline: (I2) DEPLOY_HINTS severed STEP2→STEP14 + (I3) --skip-seo flag dropped → both now forwarded via PACKAGE (parent resolved-list + dispatch template; child INPUT contract + gate); (I1) §7/§8 annex numbering drift in STEP 13/14 (operative steps said §6/§7 = stale 5-chapter scheme) realigned to authoritative §7/§8 + hard-rule renumbering M1/M2/M3 (Chapter 2/3/4 caps → 3/5/6; chapters 1–3 → 1–5, matching the gate windows). census lock added: lacks 'Agent(' on child (M5). census 47/0, shellcheck clean. Branch NOT merged (awaiting human signal). - wave-4 FINAL REVIEW (opus whole-branch): all 7 deliverable invariants hold, child gate-free, PACKAGE complete. Found 3 real regressions from the split — FIXED inline: (I2) DEPLOY_HINTS severed STEP2→STEP14 + (I3) --skip-seo flag dropped → both now forwarded via PACKAGE (parent resolved-list + dispatch template; child INPUT contract + gate); (I1) §7/§8 annex numbering drift in STEP 13/14 (operative steps said §6/§7 = stale 5-chapter scheme) realigned to authoritative §7/§8 + hard-rule renumbering M1/M2/M3 (Chapter 2/3/4 caps → 3/5/6; chapters 1–3 → 1–5, matching the gate windows). census lock added: lacks 'Agent(' on child (M5). census 47/0, shellcheck clean. Branch NOT merged (awaiting human signal).
- waves 1-4 MERGED to develop (d8917bf). LRN-126/127 added.
- post-merge RONDE (user "fais une ronde"): 4 big-model analyzer audits over 72 skills + 21 agents. Verdict: dispatch-graph INTACT (0 regressions), loops CLOSE (0 broken), tiering CORRECT (every dispatched agent), client-handover data-flow wired. The refactor preserved/improved everything it touched. NOTE: darwin-skill is a skill-PROMPT optimizer (mutates SKILL.md) — wrong tool for a post-merge verify; used bespoke analyzer fan-out on the big model (audit=reflection, dogfooded). Ronde surfaced edge findings → fixed on bugfix/model-routing-edge-fixes: F1 feater applier severed CONTRACT (real bug, LRN-126 instance — /seo,/geo dispatch feater as L1 applier with no CONTRACT but it mandated "read CONTRACT FIRST"; gave it hotfixer's applier carve-out); F2 /refactor inline-load→dispatch refactorer (sonnet pin was inert); F3 /analyze +MODEL GATE (ungated reflection); F4 interviewer drop inert sonnet pin; F5 census locks the ABSENT pin on seo/geo/validator-analyzer + client-handover-writer + interviewer (a stray sonnet pin would silently downgrade a live audit). census 47→57. Branch NOT merged.
+18
View File
@@ -1,5 +1,23 @@
# TODO # TODO
## 2026-07-16 — model-routing edge fixes (bugfix/model-routing-edge-fixes)
Post-merge ronde (4 big-model audits: dispatch-graph INTACT, loops CLOSE,
tiering CORRECT, data-flow client-handover wired). Fixing the edge findings
the ronde surfaced. Branch off develop, unmerged — human gate.
- [x] F1 (real bug) feater applier carve-out — /seo,/geo dispatch feater as
L1 applier with NO CONTRACT, but feater mandates "read CONTRACT FIRST"
(hotfixer has the carve-out, feater didn't) → mirror hotfixer.md:16-45.
- [x] F5 (guard) census: lock the ABSENT model: pin on seo/geo/validator-
analyzer + client-handover-writer (stray sonnet pin would silently
downgrade a live audit, uncaught).
- [x] F4 (cleanup) drop interviewer's inert `model: sonnet` (reflection role,
inline-loaded by gated init-project) + census guard.
- [x] F2 (tier) /refactor inline-load → true-dispatch refactorer (sonnet pin
was inert). refactorer verified dispatch-safe (no Ask/Agent, input=target).
- [x] F3 (gate) /analyze add MODEL GATE (inline-loads the analyzer reflection
agent, was ungated + undocumented). census: +analyze gated, +refactor excluded.
- [x] verify: census 57/0, shellcheck clean (my files), full suite green; NO merge.
## 2026-07-15 — model routing (feature/model-routing) ## 2026-07-15 — model routing (feature/model-routing)
Spec + plan in docs/superpowers/ (transient, BDR-065). BDR-066. Branch Spec + plan in docs/superpowers/ (transient, BDR-065). BDR-066. Branch
unmerged — human gate. unmerged — human gate.
+19 -4
View File
@@ -7,9 +7,17 @@ model: sonnet
# FEATER — plan executor # FEATER — plan executor
You receive a CLOSED plan from the /feat orchestrator. Your job is faithful You execute work ALREADY decided upstream — faithful execution, not design.
execution, not design. The thinking already happened; every choice you would The thinking already happened; every open choice is a NEED-DECISION to
want to make was either made in the plan or is a NEED-DECISION to report. report, never an improvisation. Two dispatch sources, same job:
- **/feat orchestrator** — a CLOSED plan + CONTRACT (see INPUT).
- **audit dispatchers (/seo, /geo)** — you are the L1 fix-bundle applier for
the larger items (new legal/city pages, `.htaccess`, sitemaps); the
dispatch prompt hands you a bundle item inline (files, concern, current,
expected fix) with NO CONTRACT. Apply exactly that item, self-verify, do
not commit. There is no FILE SCOPE contract on this path — the named files
in the item ARE the scope.
## INPUT (in the dispatch prompt) ## INPUT (in the dispatch prompt)
@@ -21,13 +29,20 @@ want to make was either made in the plan or is a NEED-DECISION to report.
- `GAPS` (re-dispatch only): verifier/security verdict lines — fix ONLY - `GAPS` (re-dispatch only): verifier/security verdict lines — fix ONLY
those, touch nothing else. those, touch nothing else.
Applier path (/seo, /geo): no CONTRACT/PLAN/BRANCH keys — the bundle item in
the prompt is the work to apply. Skip the contract read; the `## OUTPUT`
report below is optional on this path (the dispatcher needs the edit applied
+ self-verified, not the report grammar).
## EXECUTION RULES ## EXECUTION RULES
- Follow the plan to the letter. A plan hole or an open choice (naming, - Follow the plan to the letter. A plan hole or an open choice (naming,
data shape, API surface, dependency) → STOP, report `NEED-DECISION` with data shape, API surface, dependency) → STOP, report `NEED-DECISION` with
the precise question. Never improvise a design decision. the precise question. Never improvise a design decision.
- Stay inside the contract FILE SCOPE. A needed file outside it → - Stay inside the contract FILE SCOPE. A needed file outside it →
`NEED-DECISION` (the orchestrator owns scope changes); don't touch it. `NEED-DECISION` (the orchestrator owns scope changes); don't touch it. On
the applier path the scope is the files named in the bundle item — apply
only those.
- Write tests alongside the code, as the plan names them. Run the relevant - Write tests alongside the code, as the plan names them. Run the relevant
suite incrementally; run it fully before reporting. suite incrementally; run it fully before reporting.
- Follow existing code patterns and CLAUDE.md limits (function size, - Follow existing code patterns and CLAUDE.md limits (function size,
-1
View File
@@ -2,7 +2,6 @@
name: interviewer name: interviewer
description: Gather project info. Ask targeted questions, produce PROJECT BRIEF. First step of project init. description: Gather project info. Ask targeted questions, produce PROJECT BRIEF. First step of project init.
tools: Read tools: Read
model: sonnet
--- ---
# INTERVIEWER # INTERVIEWER
+16 -4
View File
@@ -9,12 +9,12 @@ has() { if grep -qF "$2" "$R/$1"; then ok; else ko "$1 missing: $2"; fi; }
lacks() { if grep -qF "$2" "$R/$1"; then ko "$1 must NOT contain: $2"; else ok; fi; } lacks() { if grep -qF "$2" "$R/$1"; then ko "$1 must NOT contain: $2"; else ok; fi; }
fm_lacks() { if awk 'NR<=10' "$R/$1" | grep -qF "$2"; then ko "$1 frontmatter must NOT contain: $2"; else ok; fi; } fm_lacks() { if awk 'NR<=10' "$R/$1" | grep -qF "$2"; then ko "$1 frontmatter must NOT contain: $2"; else ok; fi; }
# 1) gate wired in the 14 reflection orchestrators # 1) gate wired in the 15 reflection skills (orchestrators + /analyze)
for s in ship-feature init-project feat bugfix onboard seo geo web-validate harden audit-delta tour code-clean hotfix client-handover; do for s in ship-feature init-project feat bugfix onboard seo geo web-validate harden audit-delta tour code-clean hotfix client-handover analyze; do
has "skills/$s/SKILL.md" 'lib/model-gate.md' has "skills/$s/SKILL.md" 'lib/model-gate.md'
done done
# 2) gate NOT wired in the excluded skills (encodes the spec exclusion list) # 2) gate NOT wired in the pure-execution/read-only skills (exclusion list)
for s in commit-change doc status release-candidate; do for s in commit-change doc status release-candidate refactor; do
lacks "skills/$s/SKILL.md" 'lib/model-gate.md' lacks "skills/$s/SKILL.md" 'lib/model-gate.md'
done done
# 3) executor + gate pins # 3) executor + gate pins
@@ -53,6 +53,18 @@ has "agents/handover-doc-writer.md" 'model: sonnet'
lacks "agents/handover-doc-writer.md" 'AskUserQuestion' lacks "agents/handover-doc-writer.md" 'AskUserQuestion'
lacks "agents/handover-doc-writer.md" 'Agent(' lacks "agents/handover-doc-writer.md" 'Agent('
has "agents/client-handover-writer.md" 'subagent_type="handover-doc-writer"' has "agents/client-handover-writer.md" 'subagent_type="handover-doc-writer"'
# 10) post-merge edge fixes (ronde): F1 feater applier carve-out, F2 /refactor
# dispatch + pin, F3 /analyze gated (in loop 1), F4 interviewer un-pinned,
# F5 audit agents' ABSENT pin locked (a stray sonnet pin would silently
# downgrade a live audit even though the skill's gate passed)
has "agents/feater.md" 'Applier path'
has "skills/refactor/SKILL.md" 'subagent_type="refactorer"'
has "agents/refactorer.md" 'model: sonnet'
fm_lacks "agents/seo-analyzer.md" 'model:'
fm_lacks "agents/geo-analyzer.md" 'model:'
fm_lacks "agents/validator-analyzer.md" 'model:'
fm_lacks "agents/client-handover-writer.md" 'model:'
fm_lacks "agents/interviewer.md" 'model:'
printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail" printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail"
[ "$fail" -eq 0 ] [ "$fail" -eq 0 ]
+4
View File
@@ -5,6 +5,10 @@ argument-hint: <file/area to analyze — OR paste error/stack trace for DEBUG mo
allowed-tools: Read, Grep, Glob, Bash allowed-tools: Read, Grep, Glob, Bash
--- ---
MODEL GATE (blocking): run `$HOME/.claude/lib/model-gate.md` BEFORE anything
below. Verdict `small` → STOP — print the gate's remedy, end the turn, run
no analysis. Deep factual analysis is reflection; it needs the big model.
Load and follow strictly: Load and follow strictly:
- $HOME/.claude/agents/analyzer.md - $HOME/.claude/agents/analyzer.md
+12 -4
View File
@@ -2,11 +2,19 @@
name: refactor name: refactor
description: 'Improve code quality without changing behavior — strict norm enforcement, targeted scope (file/module). Full-codebase audit+cleanup → /code-clean. Triggers: "refactor", "clean up code", "normaliser".' description: 'Improve code quality without changing behavior — strict norm enforcement, targeted scope (file/module). Full-codebase audit+cleanup → /code-clean. Triggers: "refactor", "clean up code", "normaliser".'
argument-hint: <file, function, or module to refactor> argument-hint: <file, function, or module to refactor>
allowed-tools: Read, Write, Edit, Grep, Glob, Bash allowed-tools: Read, Write, Edit, Grep, Glob, Bash, Agent
--- ---
Load and follow strictly: `$HOME/.claude/agents/refactorer.md`. Dispatch the refactorer executor — behavior-preserving norm application is
closed execution, so it runs pinned on **sonnet** (not the big session
model). The scope you name is the only reflection; the agent applies norms.
If unreachable, emit `Refactorer agent missing.` and STOP. Never improvise — silent behavior change is unsafe. ```
Agent(subagent_type="refactorer")
prompt: "Refactor to strict project norms, preserving external behavior
exactly (zero behavioral regression, existing tests must pass). Target:
$ARGUMENTS"
```
$ARGUMENTS If the refactorer agent is unavailable, emit `Refactorer agent missing.` and
STOP — never improvise, silent behavior change is unsafe.