5.5 KiB
CONTRACT — model-router-w3c-forget
- date: 2026-10-11 | flow: feat | branch: feature/model-router-confirm (continues W3-A/B before their merge)
- status: active
REQUEST (verbatim — IMMUTABLE)
d'ailleurs est-ce quil y a une comande pour clear les decision prise ? si jamais cest un user aure que moi si il peut clean me decisions de routage ?
[orchestrator proposal: /route forget <nom|all|projects> + an optional per-user decisions file] → "seulement le forget"
CLARIFICATIONS
Q: scope / A: /route forget only; no per-user decisions file (the tracked routing.json stays the shared memory; another user inherits and may forget) [gated 2026-10-11]
Q: public shape (orchestrator default, user may veto): /route forget <name> (a skill row, an agent row or a phase), /route forget all, /route forget projects; forgetting a changed row RESTORES it to its shipped phase (changed.from); the frontmatter floors are never touched (the answer says so when a changed row is restored) [stated 2026-10-11]
Q: GATE 1 cap (verifier ECARTS(2) incl. one real defect ForgetPlan → Plan, then ECARTS(2)/(2) coverage only; 284 kit tests) / A: user "Accepter et commiter"; security PASS (1 MEDIUM + 4 LOW parked in TODO); live T3 Keeps on orchestrate and escalate seen during the run [gated 2026-10-11]
ACCEPTANCE CRITERIA
-
/route forget <name>(composer only, exactly one argument): for every kind (skills, agents, phases) removesconfirmed.<kind>.<name>; restores achangedrow to itsfromonly whenfromis a string, the row exists, equalschanged.toandfromis a known phase (else the entry is kept and the answer says why); removes everyprojects[*].<kind>.<name>(emptied tables pruned); drops the key(s) from this session's asked set; nothing removed and nothing asked → "nothing to forget for " with NO write; key only asked this session → reset, no write; refused while a dialog is open; two words → usage. One kit test per clause (folded where one setup proves two). -
/route forget alland/route forget projectsASK FIRST (engine dialog, options Cancel / Forget, Cancel first; anything else, dismissed or headless = cancelled, nothing written; skipped when there is nothing to forget; the forget holds the single-dialog slot while asking):allemptiesconfirmed,changed(rows restored under the same guards) andprojectsand clears the asked set;projectsempties onlyprojects. One kit test per clause. -
Writes go through the existing writer only (
writeRouting: serialized, size-capped, refused when the file is absent or unparsable with the existing toast, config rebuilt after the write); the model (route tool, prompt rules, sub-agents) can never trigger a forget; a non-composer origin is refused like the other/routewrites. Judged by reading + one kit test (route tool cannot forget) + the existing origin test extended. -
One answer formatter: "forgot : confirmed, row(s) restored, project exception(s) removed"; a restored row adds "(. → : at ; if <agents/.md | skills//SKILL.md> was aligned to , set model: , effort: and its lock in lib/tests/model-routing.test.sh, then
make test)" (no file clause for a built-in agent: Explore, Plan); "; ~/.claude/model-router.json still sets and wins here" when the machine override pins it; "; current run may keep : /route clear to apply" when the run slot came from a restored skill row [wording per plan r3, gated 2026-10-11]; write outcomes: refused → "nothing saved", rebuild failure after a landed write → "saved, config not rebuilt: /route reload". Write outcomes: refused → "nothing saved", rebuild failure after a landed write (dedicated error) → "saved, config not rebuilt: /route reload", any other failure → "forget not applied". One kit test per text. -
lib/effort-shift.mdnames/route forgetin ≤ 2 changed lines; README.md, USAGE.md and CHANGELOG.md no longer claim that only a dialog answer or/route askwrites routing.json (one clause each naming/route forget); the register.ts writer comment says the same;/route pendinglists a forgotten key again. CHECK: grep -q 'forget <name|all|projects>' mods/model-router/hooks/register.ts && grep -q '/route forget' lib/effort-shift.md && [ "$(wc -l < lib/effort-shift.md)" -le 66 ] && grep -q 'route forget' README.md && grep -q 'route forget' USAGE.md && grep -q 'route forget' CHANGELOG.md && ! grep -q 'Only a dialog answer or/route ask on|offwrites' README.md && echo W3C-DOC EXPECT: W3C-DOC EVIDENCE: MET exit=0 marker-found :: W3C-DOC -
Kit suite, mods suite and validate green; the census stays green on the shipped file. 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 '[1-9][0-9]* fail' && claude plugin validate . 2>&1 | grep -q 'passed' && cd ../.. && make test suite=lib/tests/mods.test.sh 2>&1 | grep -q 'all suites green' && bash lib/tests/effort-routing.test.sh >/dev/null 2>&1 && echo W3C-GREEN EXPECT: W3C-GREEN EVIDENCE: MET exit=0 marker-found :: W3C-GREEN
-
Live smoke (orchestrator + user, after the gates, recorded
[gated]): one/route forgettyped in the terminal opens its dialog ($.ui.askfrom an immediate command) and the answer lands in routing.json.
FILE SCOPE
mods/model-router/hooks/register.ts, mods/model-router/hooks/register.test.ts, lib/effort-shift.md, README.md (one clause), USAGE.md (one clause), CHANGELOG.md (one clause under Unreleased)