forked from bchanot/claude
Merge feature/model-tiering-w6-doctrine into develop
This commit is contained in:
@@ -1058,3 +1058,6 @@ Supersedes the "Excluded: hotfix" clause of [[BDR-075]]. hotfix now wired (STEP
|
||||
|
||||
### BDR-076 — Dispatched judgment agents pinned OPUS; session model = orchestration + inline reflection ONLY [accepted] (2026-07-19)
|
||||
Reverses the BDR-066 rejected alternative "opus pins on audit agents (session-independent)". Context changed: session default now Fable (Mythos tier, /model 2026-07-19) — inherit meant every dispatched audit/challenge burned Fable quota, exactly the waste BDR-066 killed for executors. New rule: Fable does ONLY main-loop orchestration + reflection (brainstorm, plan, contract, synthesis, gates); EVERY dispatched subagent pinned. Pinned `model: opus` (big tier, session-independent; NEVER sonnet — silent audit downgrade, the thing old §F5 guarded): analyzer, plan-challenger, seo-analyzer, geo-analyzer, validator-analyzer + onboard's 6 general-purpose audit dispatches (`model="opus"`) + tour Phase B. NOT pinned (justified deviation from approved "7 agents"): interviewer + client-handover-writer — inline-load only, never dispatched → frontmatter pin inert + misleading (BDR-066 wave-4 precedent: its inert opus pin was dropped); they ARE the main loop = Fable per the rule. Explore built-in stays inherit (wave-3 decision conserved: no owned prompt, search feeds inline reflection). Local session pin `opus-4-8[1m]` dropped from `.claude/settings.local.json` (gitignored) — Fable default from settings.json now applies in this repo too. model-gate.md unchanged (still guards inline reflection, Fable-or-Opus = big). Census: model-routing.test.sh §3 flip + §11 (61 pass), loops-light 35 pass, full `make test` green. User directives via gate: "Opus partout" + "Supprimer le pin". Branch feature/opus-pin-audit-agents, unmerged.
|
||||
|
||||
### BDR-077 — Model-tiering v2: 4-tier explicit routing, mode-based splits, no-inherit dispatches [accepted] (2026-07-19)
|
||||
Supersedes BDR-076 scope + amends BDR-066. Doctrine: session model (Fable) = main-loop reflection/orchestration/planning/logic ONLY; main-loop retention criteria = interactive | conversation-context access | orchestration decision | dispatch overhead > step cost. NOTHING dispatched inherits: typed agents = frontmatter pin, built-ins = `model=` at every call site (`fable` for skill-runner reflection children, else complexity tier). Spike+smoke proven: `model:"fable"` resolves claude-fable-5 (enum-validated, loud fail, no silent fallback); call-site override BEATS a typed pin (sonnet-pinned verifier ran haiku). Fail-safe pin rule: mixed-mode agents keep the HIGH tier as pin, overrides go DOWN — forgotten override over-tiers (cost), never downgrades judgment. Mode-based splits (commit-changer precedent generalized; file splits rejected): doc-syncer audit(opus)/patch(sonnet) — ALSO fixed a latent defect: /doc dispatched an agent whose STEP 8 interactive gate could never fire; gates hoisted to a DISPATCHER PROTOCOL section; handover-doc-writer synthesize(opus)/render(sonnet) via run-scoped `.audit/handover-draft-<RUNID>.md` + DRAFT COMPLETE sentinel; seo/geo collect(sonnet)/judge(OPUS PIN)/template(sonnet) via `.audit/*-signals-<RUNID>.md` + COLLECTION COMPLETE + fail-closed judge + dispatcher ERROR contract (mute/ERROR judge NEVER carried into templating; retry once, escalate). File split only for a genuinely new role: plugin-probe (sonnet, facts-only) + plugin-advisor repinned opus reasoner (fail-closed on missing PROBE REPORT) + lib/plugin-gate.md (checkpoint + apply gate, doc-commit ×N include pattern). Inline→dispatch conversions: scaffolder, onboarder, doc-commit steps ×5 flows — their sonnet pins were INERT since creation, now live; CHANGE SUMMARY crosses the doc dispatch into doc-commit (LRN-126 wire). Tier moves: validator-analyzer opus→sonnet (deterministic runner); commit-changer propose=opus/apply=pin; ship-feature/init-project code-review dispatches = opus explicit (WAS an inherit leak); client-handover-writer's 7 skill-runners = model:"fable". Every wave shipped an IN-WAVE planted-input smoke as its merge gate — all PASSED disk-verified. Census §12-18 (125 pass; one vacuous line-wrapped lock self-caught = LRN-093 live). 6 waves, branches feature/model-tiering-w1..w6, merged on user standing signal. Plan: challenged 3 blind lenses + 1 confirmation (1 BLOCKER closed by spike, 8 MAJORs + 8 MINORs closed by named changes, 0 deferred). Refs: `.claude/tasks/plans/2026-07-19-model-tiering-v2-{analysis,plan}.md`.
|
||||
|
||||
@@ -412,3 +412,4 @@ rules:
|
||||
|
||||
## 2026-07-19
|
||||
- BDR-076: dispatched judgment agents pinned opus (analyzer, plan-challenger, seo/geo/validator-analyzer + 6 onboard general-purpose dispatches); Fable now = inline orchestration/reflection only. interviewer + client-handover-writer left unpinned (inline-load, pin inert). Local opus-4-8 session pin dropped from settings.local.json. Census §11 added (61 pass), loops-light 35, make test green. feature/opus-pin-audit-agents, UNMERGED.
|
||||
- BDR-077 model-tiering v2 SHIPPED: 6 waves (W0 baseline merge → W1 no-inherit+fable skill-runners → W2 plugin split + doc two-mode + inert-pin conversions → W3 tier moves → W4 handover two-mode → W5 seo/geo 3-mode pipelines → W6 doctrine sweep). Plan challenged 4 passes (1 BLOCKER closed by fable spike). Per-wave planted-input smokes disk-verified. Census 125/0, make test green throughout. [[BDR-077]] [[LRN-137]].
|
||||
|
||||
@@ -1342,3 +1342,10 @@ rules:
|
||||
|
||||
### LRN-136 — config-protection live state follows checked-out branch's symlinked settings.json (2026-07-17)
|
||||
~/.claude/settings.json is a SYMLINK to the repo settings.json; Claude Code hot-reloads settings on change → the config-protection PreToolUse hook's active/inactive state tracks the CURRENT branch's settings.json. On feature/drop-config-protection (hook deregistered) a protected edit passed silently, sentinel unconsumed; after gitflow-switch to a branch off develop (hook still registered) the SAME class of edit was blocked. Apply: a change that removes a settings-registered hook is live only on that branch until merged; use the one-shot sentinel for protected edits on any branch that still registers it. ([[BDR-074]] context.)
|
||||
|
||||
## LRN-137 — mode-based re-tiering beats file splits for mixed-tier agents
|
||||
- **pattern**: three planned agent splits (doc-syncer, handover-doc-writer, seo/geo analyzers) shipped as MODES + per-dispatch `model=` instead of new files; only plugin-probe justified a real new file (genuinely new role, no shared body).
|
||||
- **why**: a file split severs implicit data paths (LRN-126), relocates body-text test locks (seo-data fetch-wiring), breaks name/dispatch-string census locks, duplicates templates. A mode split keeps ALL locks and text in place; the dispatcher's gate sits BETWEEN mode dispatches; call-site `model=` precedence over the frontmatter pin is spike-proven (sonnet-pinned verifier ran haiku on override).
|
||||
- **fail-safe pin rule**: keep the HIGHEST tier as the frontmatter pin and override DOWN at call sites — a forgotten override then over-tiers (costs money) instead of silently downgrading judgment (costs correctness).
|
||||
- **future application**: before splitting any agent across model tiers, try MODE + `model=` first; create a new agent file only for a genuinely new role. Run-scoped `.audit/<name>-<RUNID>` files + completeness sentinel + fail-closed consumer for any cross-dispatch artifact.
|
||||
- **cousin**: [[LRN-125]] [[LRN-126]] [[BDR-077]].
|
||||
|
||||
@@ -265,6 +265,26 @@ W6 DOCTRINE + CLOSE-OUT: model-gate.md rewrite (protects main loop; tier
|
||||
- simplicity: CONCERNS(1) — 3-way seo/geo YAGNI → 2-way worker/judge (fixed
|
||||
S3/S4); twin-templater share (dissolved by 2-way; divergence stated);
|
||||
plugin gate ×4 copies → lib/plugin-gate.md include (fixed S1).
|
||||
## EXECUTION NOTES (2026-07-19 — as-built deviations, all justified in-commit)
|
||||
|
||||
- S2/S3/S4/S5 shipped MODE-BASED (one agent, modes + call-site `model=`)
|
||||
instead of file splits — the challenge's own commit-changer precedent
|
||||
generalized; locks and body text stayed in place (LRN-137). plugin S1
|
||||
kept the `plugin-advisor` NAME for the reasoner (repinned opus) — only
|
||||
plugin-probe is a new file.
|
||||
- seo/geo keep the OPUS pin (not sonnet+judge-override): fail-safe
|
||||
direction — a forgotten override over-tiers, never downgrades. /harden
|
||||
narrow-scope + /onboard report-only keep legacy no-MODE single-shot on
|
||||
that pin.
|
||||
- W0's seo-geo-integrity arbitrage was phantom (branch already merged) —
|
||||
TODO.md corrected instead.
|
||||
- Per-wave smokes ran in-wave as merge gates (confirmation-pass fix) —
|
||||
all PASSED, disk-verified. Registry note: a NEW subagent_type registers
|
||||
at next session start; typed resolution re-checked post-restart before
|
||||
the W2 merge.
|
||||
|
||||
## CHALLENGE LOG (final)
|
||||
|
||||
- Confirmation pass (fresh robustness challenger on v2): CONCERNS(2) — v1
|
||||
fixes HOLD (doc-commit CHANGE SUMMARY, plugin-probe sonnet, rollback order,
|
||||
fable spike, RUNID); 2 new MAJORs + 1 MINOR opened by the revisions, all
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: client-handover-writer
|
||||
description: Final ship-and-handover orchestrator — called by /client-handover. Runs the audit/fix/gate pipeline (SEO+GEO+HARDEN to ≥17/20, live VALIDATE) inline on the big session model, then delegates the non-technical client deliverable (Markdown + branded HTML + PDF) to the sonnet-pinned handover-doc-writer.
|
||||
description: Final ship-and-handover orchestrator — called by /client-handover. Runs the audit/fix/gate pipeline (SEO+GEO+HARDEN to ≥17/20, live VALIDATE) inline on the big session model with fable-pinned skill-runner children, then delegates the client deliverable to the two-mode handover-doc-writer (synthesize opus / render sonnet — BDR-077).
|
||||
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch, AskUserQuestion, Agent
|
||||
---
|
||||
|
||||
@@ -1130,3 +1130,7 @@ Parse the returned `HANDOVER-DOC REPORT`:
|
||||
- `STATUS: BLOCKED` → surface the report verbatim (including which
|
||||
PACKAGE field the doc-writer flagged) and stop — do not retry or
|
||||
patch the PACKAGE silently.
|
||||
|
||||
In BOTH branches, then clean the transient draft:
|
||||
`rm -f ".audit/handover-draft-${RUNID}.md"` (run-scoped, gitignored —
|
||||
cleanup keeps `.audit/` from accumulating stranded drafts).
|
||||
|
||||
@@ -380,9 +380,10 @@ Omit any section whose delegated target does not exist and is not being
|
||||
proposed this run (e.g. drop "Deploy" entirely when `DEPLOY_COMPLEXITY`
|
||||
is `NONE`/`TRIVIAL`; drop "Configuration" when there is no config schema).
|
||||
|
||||
Tag as **AUTO** — create on first audit. Surface the rendered README in
|
||||
the validation gate before writing so the user can `edit` if needed, but
|
||||
do NOT skip creation; "skip" is not an offered option on README bootstrap.
|
||||
Tag as **AUTO** — create on first audit. The rendered README is a DRAFT
|
||||
inside the audit report (`[CREATE-AUTO]` in the PATCH PLAN); the
|
||||
DISPATCHER's gate surfaces it so the user can `edit`, but do NOT skip
|
||||
creation; "skip" is not an offered option on README bootstrap.
|
||||
|
||||
### STEP 6 — DEPLOY.md GATE
|
||||
|
||||
@@ -669,9 +670,10 @@ Last updated: <date> (<N commits since>)
|
||||
|
||||
CHANGELOG entries always HUMAN. DEPLOY.md creation always HUMAN.
|
||||
CLEAN removals always HUMAN.
|
||||
**README.md creation is AUTO** — always render and write, never gate on
|
||||
user input. The validation gate (STEP 8) still surfaces the rendered
|
||||
file so the user can edit before write, but "skip" is not an option for
|
||||
**README.md creation is AUTO** — always render (audit mode: as a draft
|
||||
in the report) and write (patch mode), never gate on user input. The
|
||||
DISPATCHER's validation gate still surfaces the rendered draft so the
|
||||
user can edit before the patch dispatch, but "skip" is not an option for
|
||||
README bootstrap; it is mandatory.
|
||||
|
||||
If no drift in any doc and no missing required doc (and, in CLEAN MODE,
|
||||
|
||||
@@ -46,8 +46,8 @@ Detect signals from REQUEST + the PROBE REPORT fields:
|
||||
| `skill-creation` | "create a skill", "new skill", "custom skill", `/plugin-dev:create-plugin` in description |
|
||||
| `embedded` | "firmware", "bare-metal", "microcontroller", "STM32", "ESP32", "RTOS", "driver", "kernel", "bootloader" in description; **or** `platformio.ini` present; **or** linker script (`*.ld`, `*.lds`) present; **or** `Makefile` + `src/*.c` + no `package.json`/`Cargo.toml`/`go.mod`/`setup.py`/`pyproject.toml` (C project without standard ecosystems). Note: `.c` files with a Rust/Node/Go manifest = FFI binding, NOT embedded. |
|
||||
| `simple` | single file, hotfix, quick script, no frontend, no deploy |
|
||||
| `anim-lib-eligible` | output of `detect_anim_eligibility` starts with `eligible|` (React/Vue/Svelte stack) |
|
||||
| `anim-lib-installed` | `is_anim_lib_installed` returns 0 (any of motion / motion-v / framer-motion / gsap / lottie-react / react-spring / popmotion / auto-animate present) |
|
||||
| `anim-lib-eligible` | PROBE REPORT `ANIM` field: `eligibility=eligible|…` (React/Vue/Svelte stack) |
|
||||
| `anim-lib-installed` | PROBE REPORT `ANIM` field: `installed=<lib>` (any of motion / motion-v / framer-motion / gsap / lottie-react / react-spring / popmotion / auto-animate) |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -114,6 +114,7 @@ has "skills/doc/SKILL.md" 'MODE: patch'
|
||||
lacks "agents/scaffolder.md" 'INLINE-LOAD'
|
||||
for s in bugfix hotfix feat ship-feature init-project; do
|
||||
has "skills/$s/SKILL.md" 'MODE: audit'
|
||||
has "skills/$s/SKILL.md" 'doc-syncer", model="opus"'
|
||||
# shellcheck disable=SC2016 # literal $HOME wanted: matching the exact inline-load string
|
||||
lacks "skills/$s/SKILL.md" 'Load `$HOME/.claude/agents/doc-syncer.md`'
|
||||
done
|
||||
@@ -160,6 +161,9 @@ has "skills/seo/SKILL.md" 'never re-derive a score'
|
||||
has "skills/seo/SKILL.md" 'DISPATCHER ERROR CONTRACT'
|
||||
has "skills/geo/SKILL.md" 'MODE: collect'
|
||||
has "skills/geo/SKILL.md" 'geo-analyzer", model="sonnet"'
|
||||
has "skills/geo/SKILL.md" 'ERROR CONTRACT'
|
||||
has "skills/geo/SKILL.md" 'never re-derive a score'
|
||||
has "agents/handover-doc-writer.md" 'SYNTH REPORT'
|
||||
|
||||
printf 'model-routing census: %d pass, %d fail\n' "$pass" "$fail"
|
||||
[ "$fail" -eq 0 ]
|
||||
|
||||
@@ -29,9 +29,11 @@ Load and follow strictly:
|
||||
- $HOME/.claude/agents/client-handover-writer.md
|
||||
|
||||
Execute the CLIENT HANDOVER WRITER agent on this project. It runs the
|
||||
audit/fix/gate pipeline INLINE on the big session model (gated above), then
|
||||
delegates the client deliverable (Markdown + branded HTML + PDF) to the
|
||||
sonnet-pinned `handover-doc-writer` subagent (BDR-066).
|
||||
audit/fix/gate pipeline INLINE on the big session model (gated above), its
|
||||
skill-runner children dispatched `model: "fable"`, then delegates the
|
||||
client deliverable to the two-mode `handover-doc-writer` subagent —
|
||||
synthesize on opus, render (Markdown + branded HTML + PDF) on the sonnet
|
||||
pin (BDR-077).
|
||||
|
||||
The agent runs a **ship-and-handover pipeline** with explicit gates:
|
||||
|
||||
|
||||
@@ -82,8 +82,9 @@ AskUserQuestion:
|
||||
uncommitted for a later run.
|
||||
- `edit <n>` → re-dispatch `commit-changer` with `MODE: propose` and the
|
||||
user's correction for step N folded into the prompt, so all grouping /
|
||||
message judgment stays on the sonnet subagent (never redrawn inline on
|
||||
the session model); show the redrawn plan and re-ask.
|
||||
message judgment stays on the dispatched propose mode (`model="opus"`,
|
||||
BDR-077 — never redrawn inline on the session model); show the redrawn
|
||||
plan and re-ask.
|
||||
- `skip` → exit cleanly, no commits created, no `MODE: apply` dispatch.
|
||||
Note: if the propose run created a `chore/*` branch (gitflow aiguillage
|
||||
off a protected base), that branch stays checked out with the work
|
||||
|
||||
@@ -104,12 +104,14 @@ Creates: CLAUDE.md, `.claude/settings.json`, `.claudeignore`, `.gitignore`, `.en
|
||||
Verify: `git init` + build passes.
|
||||
|
||||
## STEP 5b — CREATE README
|
||||
Dispatch the doc pipeline (BDR-077): `Agent(subagent_type="doc-syncer",
|
||||
model="opus")` — `MODE: audit`, `auto-mode scope: full project`. README.md
|
||||
missing → the report carries the rendered README draft as `[CREATE-AUTO]`;
|
||||
re-dispatch `Agent(subagent_type="doc-syncer")` (sonnet pin) with
|
||||
`MODE: patch` + that plan to write it. No stop (README bootstrap is
|
||||
unconditional).
|
||||
Dispatch the doc pipeline (BDR-077):
|
||||
`Agent(subagent_type="doc-syncer", model="opus")`
|
||||
— `MODE: audit` (FULL-AUDIT path, NOT `auto-mode scope:` —
|
||||
auto-mode gates a missing README as SIGNIFICANT; the full audit's STEP 5
|
||||
renders it `[CREATE-AUTO]`, unconditional). README.md missing → the
|
||||
report carries the rendered README draft as `[CREATE-AUTO]`; re-dispatch
|
||||
`Agent(subagent_type="doc-syncer")` (sonnet pin) with `MODE: patch` +
|
||||
that plan to write it. No stop (README bootstrap is unconditional).
|
||||
|
||||
## STEP 5c — CTX7 PRE-FETCH (if fast-libs detected)
|
||||
If `fast-libs` signal was detected in STEP 0 (Next.js, React 18+, Prisma, Supabase, Drizzle, etc.):
|
||||
@@ -298,8 +300,9 @@ does NOT commit them, and `gitflow finish` integrates only COMMITTED history
|
||||
— so a patch left uncommitted never reaches the merge/PR. Same PR-stranding class as the
|
||||
STEP 10b capitalize fix (BDR-034).
|
||||
|
||||
Dispatch the doc pipeline (BDR-077): `Agent(subagent_type="doc-syncer",
|
||||
model="opus")` — `MODE: audit` + `auto-mode scope: <files changed this
|
||||
Dispatch the doc pipeline (BDR-077):
|
||||
`Agent(subagent_type="doc-syncer", model="opus")`
|
||||
— `MODE: audit` + `auto-mode scope: <files changed this
|
||||
session>`; NONE → done; `[MINOR]` plan → `MODE: patch` re-dispatch (sonnet
|
||||
pin, no gate; SHAPE ESCALATION comes back gated); SIGNIFICANT → gate here,
|
||||
then `MODE: patch` with the approved subset.
|
||||
|
||||
Reference in New Issue
Block a user