5.8 KiB
CONTRACT — model-router-w2a
- date: 2026-10-09 | flow: feat | branch: feature/model-router-w2 (to start off develop)
- status: active
- wave: W2-A (mod, plan r2). W2-B (repo migration + docs/registries as its STEP 6/7) gets its own contract after the live probe.
REQUEST (verbatim — IMMUTABLE)
tu peux lancer la vague 2
(TODO W2 line: 15 skills Skill(effort-*) → route tool calls; remove skills/effort-*, lib/effort-pins.txt/.sh, install/update steps, effort: frontmatter on skills and agents; repo agents into the mod's agents table (verify the spawn/first-step ordering first); lib/model-gate.md + lib/model-check.sh → mod rule; census tests repointed; lib/effort-shift.md rewritten; docs)
CLARIFICATIONS
(pass A: none — outcome, scope and constraints come from the TODO W2 line + plan 2026-10-08-model-router-mod.md § Wave 2)
Q: keep the five effort-* skills as typed floor levers? / A: "supprimer, j'utilise les commandes builtin si j'ai besoin" → deleted; the mod drops its Skill(effort-*) bridge and typed-slash floor code; ultrathink floor stays [gated 2026-10-09]
Q: table rows = bare level next to phases, or phases only? / A: "le pin était là car pas encore de système de routage fiable; maintenant qu'il y en a un, soit on le supprime, soit tu les remanies pour que ça fonctionne encore mieux" → reworked: rows are PHASES by role (plan/reflect/implement/write/verify/judge/mechanical), no level rows; agents routed on both axes by the mod while on (model written at spawn from the phase tier, upward only); the tracked model:/effort: frontmatter STAYS as the census-locked off-state floor (plan r3, confirmation 1/8) [gated 2026-10-09]
Q: orchestrators declare phases or effort only? / A: phases [gated 2026-10-09]
Q: (mid-run, feater NEED-DECISION, CLASS internal) a skill WITHOUT a row loaded INSIDE a sub-agent: keep the old reset of that loop's effort, or leave the loop untouched like main (A5)? / A: leave the agent loop untouched too — one rule for both loops, an unrowed helper skill (find-docs) never wipes an agent row's effort [gated 2026-10-09]
Q: GATE 1 cap (3 × ECARTS on test coverage of criterion 3 clauses, code correct ×3; last rows landed by a feater, unverified) / A: user "Accepter et commiter W2-A" — accepted on the three reports + 88-test kit suite; diagnosis: compound coverage criterion, not the code [gated 2026-10-09]
Q: model gate fate? / A: slim include (self-check + STOP when the mod could not raise), lib/model-check.sh + test deleted [gated 2026-10-09]
ACCEPTANCE CRITERIA
- The mod's kit suite is green, including the new tests of criteria 3-5. CHECK: cd mods/model-router && out="$(claude plugin test . 2>&1)" && printf '%s\n' "$out" | grep -qE '[0-9]+ pass' && printf '%s\n' "$out" | grep -qE '(^|[^0-9])0 fail' && ! printf '%s\n' "$out" | grep -qE '[1-9][0-9]* fail' && echo W2A-TESTS-GREEN EXPECT: W2A-TESTS-GREEN EVIDENCE: MET exit=0 marker-found :: W2A-TESTS-GREEN
DEFAULT_CONFIG.phaseshaswriteat work/high and a newapplyat work/low;DEFAULT_CONFIG.skillsand.agentscarry exactly the phase rows of plan r2 § Row tables (56 skill rows, 21 agent rows + Explore/Plan), every value a phase key; the "Built-ins only" comment is gone. CHECK: bash .claude/tasks/contracts/w2a-table-census.sh mods/model-router/hooks/register.ts EXPECT: W2A-TABLE-COMPLETE EVIDENCE: MET exit=0 marker-found :: W2A-TABLE-COMPLETE- A user-typed slash of a rowed skill routes main to its row (name-bound marker from
prompt.submit, origins composer|sdk|bridge, pending slot mid-turn, or no live/spawning sub-agent); a preload inside a live sub-agent without the marker leaves main; a skill WITHOUT a row leaves the route in force; a best-tier skill row lives in a separaterunMainslot that survivesturn.completeand laterroutecalls, and is dropped by/route clear,/route off, a user-typed non-best rowed skill, or a user/model; theSkill(effort-*)bridge is not sticky. Covered by kit tests. - Any rowed agent spawn (whatever
provider.plugin) withe.modelundefined gets the row's model written at spawn: full id resolved within the tier only and ranked ≥ the tier head (upward only); otherwise no write + one deduped log line; the row's effort applies on its loop from its first step unless the call carriedeffort;fork/workflowspawns and agents whoseagent.offersource is a project definition are untouched; an overrideagents: { name: null }drops a row; theroutetool answer always names the id the next main step runs on. Covered by kit tests. - Typed-floor code removed: no
slashEffort,guardedSlash,'slash'Source,typed /effort-floor word inregister.ts;EFFORT_SKILL/effortBridge(tool.call bridge) and theultrathinkfloor kept until W2-B;/routeunchanged (existing tests still green). CHECK: ! grep -qE "slashEffort|guardedSlash|'slash'|typed /effort-" mods/model-router/hooks/register.ts && grep -q 'turnFloor' mods/model-router/hooks/register.ts && grep -q 'effortBridge' mods/model-router/hooks/register.ts && echo W2A-DEAD-CODE-GONE EXPECT: W2A-DEAD-CODE-GONE EVIDENCE: MET exit=0 marker-found :: W2A-DEAD-CODE-GONE claude plugin validatepasses. CHECK: cd mods/model-router && claude plugin validate . 2>&1 | grep -qi 'valid' && echo W2A-VALID EXPECT: W2A-VALID EVIDENCE: MET exit=0 marker-found :: W2A-VALIDmake test suite=lib/tests/mods.test.shgreen. CHECK: make test suite=lib/tests/mods.test.sh 2>&1 | tail -5 | grep -q 'mods' && ! make test suite=lib/tests/mods.test.sh 2>&1 | grep -q '^FAIL' && echo W2A-MODS-SUITE EXPECT: W2A-MODS-SUITE EVIDENCE: MET exit=0 marker-found :: W2A-MODS-SUITE
FILE SCOPE
mods/model-router/hooks/register.ts, mods/model-router/hooks/register.test.ts, .claude/tasks/contracts/w2a-table-census.sh (oracle, written by the orchestrator)