Commit Graph
1148 Commits
Author SHA1 Message Date
bchanot 0efcdaa1f6 Merge bugfix/push-guard-argv into develop 2026-10-11 23:42:21 +02:00
bchanot fe7d5cdb28 fix(push-guard): argv check — a push must be git's own subcommand
The text regex becomes a prefilter. The command is split into simple
commands by an awk tokenizer (quotes, escapes, ; && || | ( ) backticks,
heredoc bodies dropped) and a push is only a simple command whose argv[0]
is git (or */git) with push or send-pack as its first non-option word.
grep "git push", git log -S, git config --get push.default, git stash
push, heredocs and commit messages quoting a push are no longer denied.
bash|sh|zsh -c scripts are re-checked (depth 3); wrappers (sudo, env,
eval, xargs, timeout, git subtree...), assignments whose value reads as
a push, a missing awk or > 2000 simple commands keep the text verdict.
Prefilter also matches "git" push (quote characters stripped).
Suite 98 -> 124 checks.
2026-10-11 23:24:39 +02:00
bchanot 37ec8e332a Merge feature/model-router-w4 into develop 2026-10-11 21:39:20 +02:00
bchanot 5389ee53e7 chore(memory): BDR-116 amendment (classifier) + EVAL-045 + journal/TODO/contract w4b — feat model-router wave 4-B 2026-10-11 21:07:04 +02:00
bchanot e54a2b5d61 feat(model-router): wave 4-B — prompt classifier
Plain composer prompts with no route in force get a turn-scoped effort
from $.model.classify (design/analysis/coding/bookkeeping/chat → phase
effort, effort only, never the model). Bounded by a 3 s clock race, a
user interrupt neither counts nor writes, three failures in a row pause
it for cooldownMinutes (one toast, status marker, cleared by /route
reload). No dialog, no routing.json write on a classified route. New
Config key `classify` (default on, pickSwitch), `/route classify on|off`
session toggle, `/route show` line and argumentHint. An explicit user
/effort beats the guess (engineBase check).

Docs: README classifier paragraph, USAGE row + sentence, CHANGELOG,
effort-shift.md. Kit suite 428 tests.
2026-10-11 21:05:29 +02:00
bchanot 4506e0711f chore(memory): BDR-116 amendment (transition logs) + journal/TODO/contract w4a — feat model-router wave 4-A 2026-10-11 18:58:04 +02:00
bchanot 86845fcac8 chore(model-router): routing.json decisions — plan-challenger kept on judge, judge phase kept (live dialogs, user Keep) 2026-10-11 18:58:03 +02:00
bchanot 68d7ea65a2 feat(model-router): wave 4-A — transition-only logs, residual hardening
verbose now logs one line per real change, built from the decision
itself: main 'fable/high → fable/xhigh (plan: skill /ship-feature)' once
per turn per transition, a hand-off line per agent dispatch deduped per
(type, target) 'main fable/high → agent verifier sonnet/xhigh (row verify,
row)', a later agent effort move, and an answered-by anomaly for agents.
The four stream lines (step, answered by, spawn, route JSON, skill path)
are gone; the host prefixes the plugin name, so the new lines carry none.
Lines are built inside safely before next (a log failure never unroutes a
step); names are cleaned (≤ 40 code points). Residuals: failure texts go to
the log with a generic answer (forget, ask), file fragments cleaned at
render, floorFile name allowlisted, __proto__ refused in restoreOf, the
changed scan limited to rows, dialog Change offers only shipped phases,
a post-answer write failure keeps the key asked. Kit suite 284 → 358.

Contract .claude/tasks/contracts/2026-10-11-model-router-w4a-logs-residuals-1637.md,
plan r3: 3 lenses (BLOCKER: agent model moves are decided at spawn) + 1
confirmation, feater + 4 rounds, GATE 0 MET, verifier at the cap on
coverage (user-accepted), security PASS + 2 MEDIUM fixed.
2026-10-11 18:56:14 +02:00
bchanot f1cea54f41 Merge feature/model-router-confirm into develop 2026-10-11 16:20:01 +02:00
bchanot 119c2e2fc8 chore(memory): BDR-116 amendment (forget) + journal/TODO/contract w3c — feat model-router wave 3-C 2026-10-11 16:15:29 +02:00
bchanot e31db7b3f3 chore(model-router): routing.json decision — escalate phase kept (live first-use dialog, user Keep) 2026-10-11 16:15:29 +02:00
bchanot cd8d72f01f feat(model-router): wave 3-C — /route forget <name|all|projects>
Clears first-use decisions from the tracked routing.json through the
existing writer: a name is forgotten in every table (confirmed, changed
with the row restored to its recorded shipped phase under guards, project
exceptions pruned) and asked again; all and projects ask a confirmation in
the engine dialog (Cancel first) and hold the single-dialog slot; nothing
is written when there is nothing to forget; the answer names what was
restored and the frontmatter floor to realign when one was aligned; the
route tool has no forget path. Docs name the new writer. Kit suite 232 → 284.

Contract .claude/tasks/contracts/2026-10-11-model-router-w3c-forget-1457.md,
plan r3: 3 lenses + 1 confirmation, feater + 3 rounds (one real defect),
GATE 0 MET, verifier at the cap on coverage (user-accepted), security PASS.
2026-10-11 16:14:59 +02:00
bchanot 563a154446 chore(memory): BDR-116 amendment + EVAL-044 + journal/TODO/contract w3b — feat model-router wave 3-B 2026-10-11 14:25:53 +02:00
bchanot 70416222b1 docs: first-use dialog with context (README, USAGE, ARCHITECTURE, CHANGELOG), security-auditor on opus — feat model-router wave 3-B 2026-10-11 14:25:53 +02:00
bchanot 938c3d1a67 chore(agents): security-auditor floor aligned to its judge row (model: opus); model-routing lock updated 2026-10-11 14:25:45 +02:00
bchanot 32b71d25b5 chore(model-router): routing.json decision — security-auditor on judge (opus/xhigh), user's answer to the new first-use dialog; changed.from restored 2026-10-11 14:11:08 +02:00
bchanot 604a6c4411 feat(model-router): wave 3-B — first-use dialog with context, model then effort on change
The dialog now explains what it asks about: the skill's description (from
its SKILL.md frontmatter, five YAML forms, first sentence, cleaned), the
agent's description (from agent.offer), the phase's new 'about' line in
routing.json, and the real model id and effort the next step runs on.
Options Later / Keep / Change; Change asks the model (fable, opus, sonnet,
haiku with their tier role), then the effort among those the phases of
that model offer, then the scope; the pair maps to an existing phase (rows
stay phase names; the row's current phase wins a tie; same phase = Keep).
A main-loop phase (T3) is Later / Keep only. A main-row change toasts the
real decision and the /route switch hint when the pick is a downgrade.
Descriptions pass a hardened read (name allowlist, stat kind, size cap)
and clean(). Kit suite 190 → 232; W3-A dialog tests migrated.

Contract .claude/tasks/contracts/2026-10-11-model-router-w3b-dialog-1240.md,
plan r3: 3 lenses (2 BLOCKERs: inline rows, phase edits) + 1 confirmation,
feater + 2 rounds, GATE 0 MET, verifier CONFORME (3rd pass), security PASS.
2026-10-11 14:10:24 +02:00
bchanot f2f404a002 chore(memory): BDR-116 + LRN-212 + EVAL-043 + journal/TODO/contract w3a — feat model-router wave 3-A 2026-10-11 11:57:56 +02:00
bchanot 5bab61e13a chore(model-router): routing.json decision — doc-syncer kept on write (live first-use dialog, user Keep) 2026-10-11 11:57:56 +02:00
bchanot 304a02d70a docs: README/USAGE first-use dialog, routing.json source + config layers, ARCHITECTURE, CHANGELOG Unreleased — feat model-router wave 3-A 2026-10-11 11:57:56 +02:00
bchanot 22455c051f feat(model-router): wave 3-A — first-use route confirmation, decision memory, project exceptions
routing.json (tracked, reached through the plugin directory) is now the
single source of the phase table and of every skill/agent row, plus the
decisions: confirmed rows/phases, changed rows (from/to) and projects
exceptions keyed by a normalized git remote (credentials never stored, no
machine paths). First use of a rowed typed skill, a rowed agent spawn or a
main-loop phase opens the engine's dialog (Later / Keep / two alternative
phases; Other = a phase name); a change asks Everywhere or This project
only. One dialog at a time, never in headless, never inside an agent,
never written by the model: only a dialog answer or /route ask writes,
serialized, size-capped, never creating the file. Layers: routing.json <
~/.claude/model-router.json; the project tree is never read. /route
pending, /route ask on|off. Census reads rows and phases from the file and
tolerates a user-changed row (WARN). Kit suite 86 → 190 tests.

Contract .claude/tasks/contracts/2026-10-10-model-router-w3a-confirm-1201.md,
plan r4: 3 lenses + 1 confirmation, feater + 4 rounds, GATE 0 MET,
verifier CONFORME then re-verify after security, security BLOCK(1) fixed
then PASS. Live: T2 dialogs answered by the user from the hot-loaded mod.
2026-10-11 11:48:25 +02:00
bchanot 45bb86ff1d Merge feature/model-router-w2 into develop 2026-10-10 11:43:59 +02:00
bchanot c1767a5032 chore(memory): BDR-115 amendment 2 + LRN-210/211 + EVAL-042 + journal/TODO/contract w2b — feat model-router wave 2 2026-10-10 11:32:58 +02:00
bchanot 6f0df37f5b docs: README model/effort routing + mod bullets, USAGE niveau d'effort, ARCHITECTURE, CHANGELOG Unreleased (Removed, Changed, breaking 3.0.0) — feat model-router wave 2 2026-10-10 11:32:57 +02:00
bchanot 1f2d33b7a6 feat(model-router): wave 2-B — orchestrators declare phases, shifters and pins removed, frontmatter = off-state floor
The 15 Skill(effort-*) citers now call mcp__model-router__route per phase
(orchestrate at a dispatch span, reflect/plan for the skill's own level,
apply at the bookkeeping tail, escalate at the verify-secure caps); built-in
judgment dispatches carry an explicit effort= param. lib/effort-shift.md is
the route doctrine, lib/model-gate.md the mod rule (route answer = witness,
/route on as remedy). Deleted: skills/effort-*, lib/effort-pins.txt/.sh,
lib/model-check.sh, their tests, the installers' re-apply blocks. The mod
drops its Skill(effort-*) bridge. The tracked model:/effort: frontmatter
stays as the off-state floor, census-locked equal to the rows
(lib/tests/effort-routing.test.sh rewritten, 140 checks; analyzer → xhigh).

Contract .claude/tasks/contracts/2026-10-10-model-router-w2b-1045.md, plan
r4 § W2-B: GATE 0 MET, verifier ECARTS(7) then CONFORME 10/10, security
PASS, full make test green (design-tool-gate env red only).
2026-10-10 11:24:54 +02:00
bchanot 65dff0e768 chore(memory): journal + TODO + contract w2a — feat model-router wave 2-A 2026-10-09 17:22:43 +02:00
bchanot bb56f3e41e feat(model-router): wave 2-A — phase rows for every repo skill and agent, run slot, typed-slash routing
Rows by role replace the pins as the live source (frontmatter stays as the
off-state floor): phases write=work/high and apply=work/low, 56 skill rows,
21 agent rows + Explore/Plan. Agents get the row's model at spawn (within
the tier, upward only, explicit params win, project-defined agents skipped
via agent.offer) and its effort per step. A typed slash of a rowed skill
routes main through a name-bound marker (composer|sdk|bridge, pending slot
mid-turn) or the idle fallback; a best-tier row lives in a runMain slot
that survives turn end and route calls. An unrowed skill leaves the route.
Typed /effort-* floor code removed (bridge kept until W2-B). The route
answer always names the id. Override rows accept null. Kit suite 58 → 88.

Contract .claude/tasks/contracts/2026-10-09-model-router-w2a-1546.md, plan
r4 .claude/tasks/plans/2026-10-09-model-router-w2-1546.md: 3 lenses + 2
confirmations, feater + 4 rounds, GATE 0 MET, verifier 3x ECARTS on test
coverage only (user-accepted at the cap), security PASS.
2026-10-09 17:22:07 +02:00
bchanot 862740da9d chore(memory): journal — make test hotfix merged, session close before wave 2 2026-10-09 15:37:29 +02:00
bchanot 5e0e5c0bc4 Merge bugfix/make-test-names-red-suites into develop 2026-10-09 15:37:17 +02:00
bchanot ca9645833c chore(memory): LRN-207/208/209 + EVAL-041 — availability signal, blind security brief, scoped test runs, W1-C challenge value 2026-10-09 15:36:59 +02:00
bchanot b09e84497a chore(memory): journal — make test summary hotfix 2026-10-09 15:31:27 +02:00
bchanot efdd491d63 fix(make): test target names every red suite and prints a summary
A full make test printed only the == headers and an aggregate exit code,
so finding the red suite meant re-running every suite one by one (the
pre-merge check of 2026-10-09 took 7.5 min for that reason). The loop now
prints FAIL <suite> as it happens and ends with 'all suites green' or
'<n> suite(s) red: <names>'; the exit code is unchanged.
2026-10-09 15:31:26 +02:00
bchanot ff741e3a82 chore(memory): journal — model-router wave 1 merged into develop 2026-10-09 15:25:39 +02:00
bchanot abbdf7926d Merge feature/model-router-mod into develop 2026-10-09 15:25:06 +02:00
bchanot a4f660d0b6 chore(tasks): model-router W1-C live checks part 1 done, part 2 queued; journal 2026-10-09 15:14:55 +02:00
bchanot 6f31f49d7c chore(tasks): model-router W1-C done — contract evidence, TODO (accepted MEDIUMs, residuals, live checks), journal 2026-10-09 15:09:07 +02:00
bchanot d0fa1001bb feat(mods): model-router adaptive tiers — absolute tiers, availability breaker, derived phases
Phases name absolute tiers (best fable>opus>sonnet, big opus>fable>sonnet,
work sonnet>opus, cheap haiku>sonnet) resolved to the first available full
id; per-model circuit breaker fed by StopFailure kinds (rate_limit,
overloaded, billing_error, model_not_found) and PostModelSwitch auto, with
episode backoff 15→300 min, cleared by a user /model or /route reload and
kept across /clear; fallback chain fable→opus→sonnet→haiku with the effort
unchanged; main loop upgrades to a phase's tier by itself under a context
cap (fails closed on unknown usage), downgrades only with the switch on,
sticky within a turn; derived orchestrate on background dispatches;
prompt default rules (plan/reflect, Unicode guards, skipped on slash
commands, floor matches and mid-turn). 58 plugin tests.
2026-10-09 15:08:49 +02:00
bchanot 977be7cad8 chore(tasks): model-router W1-C plan r3 + r4 after two confirmation passes 2026-10-09 13:22:07 +02:00
bchanot 140c16a67f chore(tasks): model-router W1-C plan r2 + contract amendments after the FATAL round 2026-10-09 12:55:14 +02:00
bchanot 2d8cd6bf4c chore(tasks): model-router W1-C contract + plan (absolute tiers, breaker fallback, derived phases) 2026-10-09 12:40:19 +02:00
bchanot e79db7e6df chore(memory): model-router wave 1 closed — TODO W2 queued, journal 2026-10-09 11:16:32 +02:00
bchanot b22f8947f9 docs: README effort routing + /route, USAGE, ARCHITECTURE mods/, CHANGELOG — model-router wave 1 2026-10-09 11:04:10 +02:00
bchanot a6e200392c chore(memory): BDR-115 amendment (skills-dir load, floor, kill switch) + journal B2 2026-10-09 10:52:28 +02:00
bchanot 3c44dd00d3 chore(tasks): model-router B2 done — contract evidence, TODO close-out queue 2026-10-09 10:51:51 +02:00
bchanot 6430ac65ec feat(mods): model-router active in every session — skills-dir link, mods suite, doctor section, CLAUDE.md
Tracked relative symlink skills/model-router -> ../mods/model-router: Claude
Code loads the mod in place as model-router@skills-dir wherever link.sh
links ~/.claude/skills (no CLAUDE_CODE_PLUGIN_DIRS: absolute paths in the
tracked settings.json). Engine-laid mods/*/tsconfig.json gitignored.
lib/tests/mods.test.sh: manifest name, link target, claude plugin validate
and test per mod, capability-probed, time-bounded, SKIP with reason.
doctor.sh: fail-soft Mods section (link by -ef, one guarded plugin list).
CLAUDE.md: mods/ section (loading, per-machine enabled:false switch,
dev-copy shadowing, tests).
2026-10-09 10:51:13 +02:00
bchanot 24e180ade0 chore(tasks): model-router B1 done — contract evidence, TODO, journal 2026-10-09 10:13:03 +02:00
bchanot 1ff608a68c feat(mods): model-router user effort floor — ultrathink and typed /effort-<l> set the main turn's default and minimum
One decision helper (mainEffort) feeds the plan and every answer text;
per-axis precedence (sticky > turn route > floor > engine); a mid-turn
prompt floors the running turn and the next; per-machine kill switch
"enabled": false in ~/.claude/model-router.json, kept across /clear and
across a failed reload; typed /effort-<l> attested at prompt.submit so a
sub-agent preload cannot floor the main loop. 30 plugin tests.
2026-10-09 10:12:28 +02:00
bchanot 868a7f0515 chore(tasks): model-router B1/B2 plans r2 after the 6-lens challenge round 2026-10-09 09:24:32 +02:00
bchanot 77ad7cf494 chore(tasks): model-router W1-B split — floor + wiring contracts/plans, skills-dir loading decision, journal 2026-10-08 18:37:32 +02:00
bchanot ae0179f491 chore(tasks): model-router contract criteria 7-11, TODO hardening done + residuals, journal 2026-10-08 16:53:43 +02:00