chore(memory): BDR-116 amendment (forget) + journal/TODO/contract w3c — feat model-router wave 3-C
This commit is contained in:
@@ -1412,4 +1412,5 @@ Branch feature/user-writing-web-rules, UNMERGED (human gate).
|
||||
- **Gates**: plan r1 → r4 (simplicity CONCERNS(3), correctness FATAL(8) with the census BLOCKER, robustness CONCERNS(8) after a network-killed first run, confirmation CONCERNS(6)); feater DONE + 4 rounds; GATE 0 MET; verifier ECARTS(3)/(2) → CONFORME, re-verify after security ECARTS(1) → fixtures; security BLOCK(1) real (password with `@`/`/` stored in the key) → fixed, PASS. Kit 86 → 190 tests. Live T2 dialogs answered by the user from the hot-loaded working-tree mod ([[LRN-212]]).
|
||||
- **Refs**: contract `.claude/tasks/contracts/2026-10-10-model-router-w3a-confirm-1201.md`, plan `.claude/tasks/plans/2026-10-10-model-router-w3a-confirm-1201.md`, commit 22455c0, [[BDR-115]], [[LRN-210]], [[LRN-211]], [[EVAL-043]].
|
||||
- **Amendment (2026-10-11, wave 3-B, commit 604a6c4)**: clause (2) superseded: the dialog carries CONTEXT (skill description = first sentence of its SKILL.md frontmatter, five YAML forms, hardened read: name allowlist, stat kind file, size cap, `clean()` Cc/Cf + code points; agent description from `agent.offer`, bounded cache; phase `about` line, new 120-char field on the 11 routing.json phases, kept in memory not on Route) and the REAL next model id + effort. Options Later / Keep / Change (T3 Later / Keep). Change = model (4 fixed alias labels with tier role) → effort among those the phases headed by that alias offer (ascending, ≤ 4, one → skipped, zero → Later) → scope; the pair maps to an existing PHASE (rows stay phase names; row's current phase wins a tie; same phase = Keep); a pair no phase offers = a new phase by hand. Other anywhere = Later + toast (no echo). A main-row change toasts the real decision + `/route switch on` hint on a held downgrade. Three lenses rejected inline-route rows and dialog phase edits (2 BLOCKERs). First real use: user moved security-auditor to `judge` (opus/xhigh) through it; floor aligned (`model: opus`, 2026-10-11). Links [[EVAL-044]].
|
||||
- **Amendment (2026-10-11, wave 3-C, commit cd8d72f)**: clause (6) extended: `/route forget <name|all|projects>` (composer only) clears decisions in the tracked file through the same writer: a name in every table (`confirmed`, `changed` → row restored to its recorded `from` when it is a string, the row still equals `to` and `from` is a known phase; `projects[*]` pruned), asked again at once; `all`/`projects` confirm through the engine dialog (Cancel first, anything else = cancelled) and hold the single-dialog slot; nothing written when nothing to forget; the answer names a restored row's file + values to realign (a floor aligned to the decision makes the census FAIL after the restore). No per-user decisions file (user: "seulement le forget"): another user inherits the shared memory and may forget. Residuals (security LOW/MEDIUM): raw error text in the answer, file fragments unsanitized in the answer, `floorFile` name not allowlisted, `__proto__` plan/apply mismatch, `changed.phases` restorable. Links [[EVAL-044]].
|
||||
|
||||
|
||||
@@ -598,3 +598,4 @@ rules:
|
||||
## 2026-10-11
|
||||
- model-router W3-A (first-use confirmation) landed 22455c0 on feature/model-router-confirm. User asked for it after the W2 merge; 3 pass-B answers. Plan r1→r4: correctness BLOCKER (Everywhere decision = census red → `changed` WARN exemption), robustness (first challenger killed by DNS, fresh one: project-tree layer dropped for security, single dialog in flight, keep-previous after first load), confirmation CONCERNS(6). Feater DONE (169 tests) + 4 rounds. Verifier ECARTS(3)/(2)/CONFORME; security BLOCK(1) REAL: password with `@`/`/` landed in the tracked key → strict parsing, no `local:` keys, output cap → re-verify ECARTS(1) fixtures → PASS. The working-tree mod was hot-loaded by the engine: my own dispatches opened T2 dialogs the user answered (verifier Keep, feater Keep, security-auditor → implement → user reset to verify); first misread as a test leak (LRN-212). GATE 0 oracle as heredoc not runnable → script. Full make test green (env red only). Docs P1-P13 user-approved (patch in flight); BDR-116, LRN-212, EVAL-043 written. Next: doc commit, memory commit, user merge + publish by hand; T1/T3 live checks open.
|
||||
- model-router W3-B (dialog with context) landed 604a6c4 + data 32b71d2 + floor chore. User asked after W3-A: explain what is decided, OK/change/later, model then effort then scope. Plan r1→r3: all three lenses killed my inline-row format and the T3 phase edit (2 BLOCKERs avoided); efforts derived from the phases of the chosen model. Feater DONE first pass (229 tests), verifier ECARTS(2)→(1)→CONFORME, security PASS. GATE 0 heredoc CHECK not runnable again → script. Live during the gates: user answered the NEW dialog for security-auditor → opus/xhigh (the request's example; kept, floor aligned to opus, model-routing lock updated), plan-challenger → verify (reset on user go), orchestrate Keep (T3 check done). My `changed = {}` reset wiped a legit entry → census red for one commit → restored. Docs P1-P6 approved (patch in flight), BDR-116 amendment + EVAL-044 written. Next: doc commit, memory commit, user merge of feature/model-router-confirm (W3-A + W3-B) + publish by hand; T1 live check still open.
|
||||
- model-router W3-C `/route forget` landed cd8d72f (+ data commit: escalate Keep). User asked whether decisions can be cleared and what another user can do; chose the command only, no per-user file. Plan r1→r3: three lenses CONCERNS (false `st.mem` premise, kind order, docs scope, census red after restoring an aligned floor, no confirmation on `all`), confirmation CONCERNS(3). Feater DONE; verifier ECARTS(2) with a REAL typo (`ForgetPlan`), then coverage only ×2 → cap → user accepted; security PASS (1 MEDIUM + 4 LOW parked). My own `route(escalate)` call opened the T3 dialog the user Kept. Branch feature/model-router-confirm now carries W3-A/B/C (14 commits), unmerged, unpushed; merge on signal; full make test running.
|
||||
|
||||
@@ -29,6 +29,8 @@ Plan `.claude/tasks/plans/2026-10-10-model-router-w3a-confirm-1201.md` r4, contr
|
||||
- [x] W3-B dialog with context (2026-10-11, 604a6c4, contract `2026-10-11-model-router-w3b-dialog-1240`, plan r3): descriptions (skill frontmatter / agent.offer / phase `about`), real id + effort in the question, Later / Keep / Change, model → effort (derived from the phases of that model) → scope, rows stay phases, T3 Later/Keep. 3 lenses (2 BLOCKERs on my r1 avoided) + 1 confirmation, feater + 2 rounds, verifier CONFORME (3rd), security PASS (4 LOW: symlinked SKILL.md read, TOCTOU, raw key in a log, any plugin hooking AskUserQuestion could answer). Live decisions: security-auditor → judge (kept, floor aligned `model: opus`), plan-challenger → verify (reset on user go), orchestrate Keep (T3 live check done).
|
||||
- [ ] W3-B residuals: a Change answered Everywhere can store a machine-only phase name (defined in `~/.claude/model-router.json`) into the tracked file (security note, correctness); SKILL.md symlink follow (LOW); `descs` cap and "(custom)" label untested; the security-auditor's `changed.from = verify` entry stays in routing.json although the floor now equals the row (harmless; prune at release).
|
||||
- [ ] trace the "auto mode: use Bash/sed instead of Edit/Write" instruction block that sub-agents see attributed to the model-router MCP instructions (security-auditor 2026-10-11): it is NOT in mods/model-router source; likely the harness's own auto-mode text rendered next to the mod's MCP block. Confirm the origin.
|
||||
- [x] W3-C `/route forget` (2026-10-11, cd8d72f, contract `2026-10-11-model-router-w3c-forget-1457`, plan r3): name/all/projects, guarded restore, confirmation dialog for all/projects, no-write paths, docs. 3 lenses + 1 confirmation, feater + 3 rounds (1 real defect: `ForgetPlan` typo), verifier at the cap on coverage (user accepted), security PASS. Kit 232 → 284. Live: orchestrate + escalate T3 Keeps seen.
|
||||
- [ ] W3-C residuals (security, accepted): `forget not applied (${String(err)})` echoes the raw writer error (send to the log); file-sourced `from`/`to`/keys unsanitized in the answer (clean() them); `floorFile` builds a display path from an unvalidated key (SKILL_NAME check); `__proto__` accepted by `restoreOf` while `setKey` refuses it (plan/apply mismatch); `changed.phases` entries restorable (limit the scan to ROWS). Live smoke of `/route forget` from the terminal still unseen (criterion 7).
|
||||
- [ ] W3-A live checks still open: T1 (typed `/feat` etc.) dialog (T3 seen live 2026-10-11: orchestrate Keep); a parallel same-agent dispatch answered after > 10 s; what an unanswered dialog resolves to on the terminal (must be Later or nothing written). Record in the contract as `[gated]` when seen.
|
||||
- [ ] W3-A residuals (security LOW, accepted): non-atomic cross-process write (two sessions, crash mid-write → file reads as failed, previous config kept); `host/path` of a private remote in the tracked file; a persistent write failure re-asks every use (`asked.delete` in the catch); `out.length` vs byte size at the cap; `changePatch` scope 'project' with a vanished key writes Everywhere (cwd change mid-dialog). Deferred: `/route set`, `/route confirm`, `(unconfirmed)` in show, dialog edits of phases, frontmatter auto-alignment, session-start warning when routing.json is dirty, per-machine `projects`.
|
||||
- [ ] routing.json ships `confirmed` for verifier/feater (user Keeps) and phases verify/implement: every clone inherits them (by design: decisions travel). Revisit at release if unwanted.
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# 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
|
||||
1. `/route forget <name>` (composer only, exactly one argument): for every kind (skills, agents, phases) removes `confirmed.<kind>.<name>`; restores a `changed` row to its `from` only when `from` is a string, the row exists, equals `changed.to` and `from` is a known phase (else the entry is kept and the answer says why); removes every `projects[*].<kind>.<name>` (emptied tables pruned); drops the key(s) from this session's asked set; nothing removed and nothing asked → "nothing to forget for <name>" 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).
|
||||
2. `/route forget all` and `/route forget projects` ASK 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): `all` empties `confirmed`, `changed` (rows restored under the same guards) and `projects` and clears the asked set; `projects` empties only `projects`. One kit test per clause.
|
||||
3. 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 `/route` writes. Judged by reading + one kit test (route tool cannot forget) + the existing origin test extended.
|
||||
4. One answer formatter: "forgot <label>: <c> confirmed, <m> row(s) restored, <k> project exception(s) removed"; a restored row adds "(<kind>.<name> → <from>: <alias> at <effort>; if <agents/<name>.md | skills/<name>/SKILL.md> was aligned to <to>, set model: <alias>, effort: <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 <name> and wins here" when the machine override pins it; "; current run may keep <phase>: /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.
|
||||
5. `lib/effort-shift.md` names `/route forget` in ≤ 2 changed lines; README.md, USAGE.md and CHANGELOG.md no longer claim that only a dialog answer or `/route ask` writes routing.json (one clause each naming `/route forget`); the register.ts writer comment says the same; `/route pending` lists 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|off` writes' README.md && echo W3C-DOC
|
||||
EXPECT: W3C-DOC
|
||||
EVIDENCE: MET exit=0 marker-found :: W3C-DOC
|
||||
6. 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
|
||||
|
||||
7. Live smoke (orchestrator + user, after the gates, recorded `[gated]`): one `/route forget` typed in the terminal opens its dialog (`$.ui.ask` from 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)
|
||||
@@ -0,0 +1,155 @@
|
||||
# PLAN r3 — model-router wave 3-C: `/route forget` (2026-10-11)
|
||||
|
||||
r1 → r2 after simplicity CONCERNS(3), correctness CONCERNS(4), robustness
|
||||
CONCERNS(4); r2 → r3 after the confirmation (correctness CONCERNS(3)).
|
||||
Precedence r3 > r2 > r1. Contract
|
||||
`.claude/tasks/contracts/2026-10-11-model-router-w3c-forget-1457.md`.
|
||||
Base W3-B (604a6c4 + 32b71d2 + 938c3d1). Corrected facts: `Memory` holds
|
||||
ok/ask/askLocal/base/confirmed/about/local/key only (no `changed`, no
|
||||
`projects`); the composer gate lives in `registerCommandHook`, not in
|
||||
`handleCommand`; `writeNow` always writes once the patch ran and toasts
|
||||
UPDATED, returns false on refusal, throws when the rebuild fails after a
|
||||
landed write; `show` prints no command list (the only visible list is the
|
||||
`argumentHint`); `routeMainBySkill` copies a route into `turnMain`/`runMain`
|
||||
and a rebuild never touches those slots; the shipped file holds one changed
|
||||
row (security-auditor verify → judge) whose frontmatter floor was aligned
|
||||
to `opus`: restoring it without re-aligning the floor makes the census
|
||||
FAIL (no `changed` entry = no WARN exemption).
|
||||
|
||||
## Behaviour (composer `/route forget <arg>`, exactly ONE argument)
|
||||
- Parsing: no arg or more than one → "usage: /route forget <name|all|projects>".
|
||||
Reserved words `all` and `projects`; a row or phase named like them
|
||||
cannot be forgotten by name (answer says "edit routing.json by hand").
|
||||
- Guard: while a dialog is open (`st.asking !== null`) → "answer the open
|
||||
dialog first", nothing written. The forget confirmation TAKES the slot
|
||||
itself (`st.asking = 'forget:<target>'` in a try/finally around `askOr`)
|
||||
so no first-use dialog opens under it and two forgets cannot stack.
|
||||
- The decision runs on the FRESH file, twice: a PRE-read (after awaiting
|
||||
`st.writes`, so a landed Keep is visible) decides the no-write paths and
|
||||
the confirmation counts; the PATCH itself re-runs `forgetPlan(file,
|
||||
target)` on `writeNow`'s own freshly read `file` (the closure exports the
|
||||
counts actually applied; the answer reports those). Pre-read missing or
|
||||
unparsable → the writer's refusal path ("routing.json is missing or
|
||||
unreadable: nothing saved"); nothing to remove, no refused restore and
|
||||
the key(s) not in `st.asked` → "nothing to forget for <name>" / "nothing
|
||||
to forget", NO write; only a refused restore → its reason, NO write;
|
||||
key(s) only in `st.asked` → reset them, NO write, "asked again at the
|
||||
next use, nothing was saved" (when the key is decided by the machine
|
||||
override or a project row, say "still decided by …" instead).
|
||||
- `<name>`: for EVERY kind in KINDS (skills, agents, phases): delete
|
||||
`confirmed.<kind>.<name>`; restore `changed.<kind>.<name>` → row =
|
||||
`from` ONLY when `from` is a string, the row exists, the row equals
|
||||
`changed.to`, and `from` is a phase of `file.phases` or
|
||||
`DEFAULT_CONFIG.phases` (else the entry is kept and the answer says
|
||||
why); delete `projects[k].<kind>.<name>` for every k, pruning an emptied
|
||||
kind table then an emptied `projects[k]`; then `st.asked.delete(key)`.
|
||||
- `all`: the same over every entry of `confirmed`, `changed`, `projects`;
|
||||
`projects`: only `projects` emptied. Both ASK FIRST through `askOr`:
|
||||
"Forget <n> decision(s): <m> row(s) restored, <k> project exception(s)
|
||||
in <r> repo(s)?" options ["Cancel", "Forget"] (Cancel first; any other
|
||||
answer, a dismissed dialog or headless = cancelled, nothing written);
|
||||
skipped when every count is zero ("nothing to forget").
|
||||
- Write: ONE `writeRouting` patch (the closure carries the counts out);
|
||||
outcomes: false → "nothing saved" (the writer's toast already explains);
|
||||
true → asked keys deleted, config rebuilt; a rebuild failure after a
|
||||
landed write is signalled by a dedicated error class (`RebuildFailed`,
|
||||
thrown by `writeNow` there and only there) → "saved, config not rebuilt:
|
||||
/route reload" (asked keys untouched); any other throw (patch, fs.write)
|
||||
→ "forget not applied (<err kind>)", asked keys untouched.
|
||||
- Answer, one formatter (used by every form, per restored row): "forgot
|
||||
<label>: <c> confirmed, <m> row(s) restored, <k> project exception(s)
|
||||
removed[, <j> restore(s) kept: <reasons>]" + per restored row " (<kind>.
|
||||
<name> → <from>: <alias> at <effort>; if <file> was aligned to <to>, set
|
||||
model: <alias>, effort: <effort> and its lock in
|
||||
lib/tests/model-routing.test.sh, then `make test`)" where `<file>` =
|
||||
`agents/<name>.md` or `skills/<name>/SKILL.md` (no file clause for a
|
||||
built-in agent such as Explore/Plan), alias = head of the phase's tier in
|
||||
the SHIPPED `DEFAULT_CONFIG.tiers` (or the phase's model), effort from
|
||||
the phase;
|
||||
+ "; ~/.claude/model-router.json still sets <name> and wins here" when
|
||||
`mem.local` has it, checked only after a successful rebuild;
|
||||
+ "; current run may keep <phase>: /route clear to apply" when a
|
||||
restored SKILL row's `to` phase equals the phase of `runMain` or
|
||||
`turnMain` with source `run`/`skill`;
|
||||
+ "; other live sessions see it after /route reload".
|
||||
- `all` prunes emptied kind tables in `confirmed`, `changed`, `projects`
|
||||
(a kept unrestorable `changed` entry stays and is reported).
|
||||
- `decisions` count = confirmed entries + changed entries + project rows
|
||||
(an entry counted once per table it sits in).
|
||||
- The route tool has no `forget`; sub-agents cannot run commands; the
|
||||
origin gate is the existing one in `registerCommandHook`.
|
||||
|
||||
## Docs and comments (same commit)
|
||||
- `argumentHint` gains `forget <name|all|projects>` (locked by a grep in
|
||||
the contract CHECK, not by a kit test); register.ts comment "Only a
|
||||
dialog answer or `/route ask` writes" → "… or `/route ask` / `/route
|
||||
forget` writes".
|
||||
- README.md: the `/route` subcommand list (~138) gains `forget
|
||||
<name|all|projects>` and the writers sentence (~140) names it;
|
||||
USAGE.md: the sentence "`/route pending` liste …, `/route ask off|on`
|
||||
…" (~190) gains `/route forget <nom|all|projects>` (efface une
|
||||
décision, la ligne revient à la phase livrée); CHANGELOG.md: the
|
||||
argument form (~10) and the writers sentence (~11); `lib/effort-shift.md`
|
||||
commands line.
|
||||
|
||||
## Steps
|
||||
- [ ] S1 `forgetPlan(file, target)` (pure over the fresh file data:
|
||||
removals, restores, counts, skipped restores with reasons) and
|
||||
`forgetCommand($, st, args)` (arity, reserved words, asking guard,
|
||||
read, no-write paths, confirmation for all/projects, write via
|
||||
`writeRouting` with a patch that applies the plan, outcome branches,
|
||||
asked reset, answer); `handleCommand` case `forget`; argumentHint.
|
||||
- [ ] S2 docs/comments above.
|
||||
- [ ] S3 kit tests, folded: forget a confirmed skill → entry gone, asked
|
||||
again in the same session, `/route pending` lists it; forget a changed
|
||||
agent → row restored, entry gone, the next spawn on the restored model,
|
||||
answer carries the realign clause with the file and values; forget a
|
||||
phase → confirmed.phases gone, T3 asks again; forget a name with a
|
||||
project exception in two repos → both rows removed, emptied keys
|
||||
pruned; undecided row → "nothing to forget", no write; asked-only key
|
||||
→ reset, no write; unknown name → "nothing to forget for", no write;
|
||||
arity (two words → usage); reserved word collision answer; open dialog
|
||||
→ refused; `all` cancelled → nothing written; `all` confirmed →
|
||||
everything empty, counts in the answer; `projects` → only projects
|
||||
emptied; restore refused (row ≠ to / from unknown) → entry kept, reason;
|
||||
override-pinned row → the "wins here" clause; restored skill with a run
|
||||
slot → the "/route clear" clause; missing file → "nothing saved";
|
||||
rebuild throw → "saved, config not rebuilt"; route tool `clear` leaves
|
||||
decisions; the existing origin test extended with `forget x`;
|
||||
`failWrite` → "forget not applied"; (argumentHint: grep lock in the
|
||||
contract, no kit test).
|
||||
- [ ] S4 live smoke after the feater (orchestrator, user): one `/route
|
||||
forget projects` (or a name) typed in the terminal with the dialog
|
||||
answered → recorded `[gated]` in the contract (`$.ui.ask` from an
|
||||
`immediate` command is unverified live).
|
||||
- Disposition: honors BDR-116 (user-only writers, same path/caps; the
|
||||
shared tracked memory stays the user's choice), LRN-210 (one clause per
|
||||
test, folded where one setup proves two clauses), LRN-212.
|
||||
|
||||
## Challenge ledger (r1 → r2)
|
||||
- simp 1, corr 1, rob 2 (false `st.mem` premise) → plan over the fresh
|
||||
file, closure counts, pre-read no-write paths.
|
||||
- simp 2, corr 2, rob 7 (kind order, reserved words, no-op writes) → all
|
||||
kinds, removed-count rule, arity, reserved-word answer.
|
||||
- simp 3, corr 4/9/10, rob (docs) → docs/comment scope, AC4 = argumentHint.
|
||||
- simp 4 (projects form) → kept, one-liner, with the confirmation.
|
||||
- simp 5/6, corr 3/7, rob 3/9 (restore + floors + validation) → guarded
|
||||
restore, realign clause with file + values, one formatter.
|
||||
- corr 5, rob 8 (override-pinned) → "wins here" clause.
|
||||
- corr 6, rob 6 (dialog in flight) → refuse while asking.
|
||||
- corr 8, rob 4 (run slot) → "/route clear" clause.
|
||||
- rob 1 (no confirmation) → askOr confirmation for all/projects, Cancel first.
|
||||
- rob 5 (three write outcomes) → branches.
|
||||
- simp 7 (test folds) → S3 folded.
|
||||
|
||||
## Confirmation ledger (r2 → r3)
|
||||
- conf 1 (throw mapping) → `RebuildFailed` class; other throws "not applied".
|
||||
- conf 2 (slot not taken) → forget takes `st.asking` around its askOr.
|
||||
- conf 3 (stale plan at write) → patch recomputes on its own file; pre-read
|
||||
awaits `st.writes`; applied counts reported.
|
||||
- conf 4 (run-slot rule) → kind skills, source run/skill, phase == `to`.
|
||||
- conf 5 (realign clause) → conditional, shipped tiers, no file for built-ins.
|
||||
- conf 6 (argumentHint test) → grep lock in the contract CHECK.
|
||||
- conf 7 (live dialog from a command) → S4 smoke.
|
||||
- conf 8 (ambiguities a-f) → sentences added.
|
||||
- conf 9 (docs anchors) → README list + USAGE anchor + CHANGELOG form.
|
||||
Reference in New Issue
Block a user