24 Commits
Author SHA1 Message Date
Bastien Chanot aeb7bc05d8 Merge chore/doc-sync-v1.2.0 into develop 2026-07-20 14:24:11 +02:00
Bastien Chanot 45e679ac23 docs: README model-routing v2 table (BDR-076/077) + ctx7 surfaces (BDR-078) + STEP 2b — post-release 1.2.0 doc pass 2026-07-20 14:21:24 +02:00
Bastien Chanot 2d38ffd843 Merge release/1.2.0 into develop 2026-07-20 14:07:28 +02:00
Bastien Chanot 56571805a1 chore(release): 1.2.0 — version.txt + CHANGELOG 2026-07-20 14:06:14 +02:00
Bastien Chanot 8ee7d19d70 Merge feature/ctx7-coverage into develop 2026-07-20 14:02:33 +02:00
Bastien Chanot b7026e4bda feat(ctx7): coverage extension — fast-libs single source + reminder hook + executor briefs (BDR-078)
- lib/fast-libs.sh: detect/cache-status verbs, JS+Python manifests,
  7-day cache freshness, LC_ALL=C sort — replaces 3 hardcoded lists
  (ship-feature 0c, init-project 5c, onboard 3.5)
- hooks/ctx7-reminder.sh: once-per-session UserPromptSubmit nudge when
  the project carries fast-libs and .ctx7-cache/ is missing/stale
- find-docs: before-writing-code trigger + cache-first rule; dist is
  machine-owned (gitignored) so the durable patch lives in
  install-plugins.sh STEP ctx7 (idempotent, grep-guarded)
- feater/bugfixer briefs: fast-lib docs rule (fresh cache read, else
  2-topic ctx7 fetch, else NOTES cache miss + proceed)
- tests: lib/tests/fast-libs.test.sh (11 checks); shellcheck + full
  make test green (review-guards 5/0)
2026-07-20 10:45:06 +02:00
Bastien Chanot 6838d5a8fa Merge feature/model-tiering-w6-doctrine into develop 2026-07-19 23:56:58 +02:00
Bastien Chanot 444c79acb2 fix(routing): W6 ronde — 6 findings closed (README bootstrap path, 2 census gaps, 3 stale refs)
Fresh-opus whole-chantier ronde (17fbe51..HEAD, EVAL-023 style): axes
severed-wires / gate-regressions / fail-open PROVEN CLEAN (all 7 new
handoffs traced end-to-end both sides). Fixed: init 5b now dispatches the
FULL-AUDIT path (auto-mode gated a missing README as SIGNIFICANT →
[CREATE-AUTO] unconditional restored, sole greenfield README path);
census locks added for /geo ERROR CONTRACT + never-re-derive (deleting
the fail-closed handler would have stayed green), doc-audit
model=opus override x5 flows, SYNTH REPORT grammar; doc-syncer ex-STEP-8
prose repointed to the dispatcher gate; plugin-advisor anim rows read
the PROBE REPORT ANIM field (no Bash anymore); client-handover 9.7
cleans the transient draft. Census caught one more line-wrapped lock
before it shipped vacuous. 133 pass / 0 fail, make test exit 0.
2026-07-19 23:56:58 +02:00
Bastien Chanot 07253e093c feat(doctrine): W6 — prose sweep + BDR-077 + LRN-137 + plan execution notes
LRN-113 whole-surface sweep: client-handover x2 + commit-change prose
repointed to the two-mode reality; code-cleaner/status historic notes
kept (accurate). Memory: BDR-077 (full architecture), LRN-137
(mode-based re-tiering + fail-safe pin rule), journal. Plan carries
as-built EXECUTION NOTES.
2026-07-19 23:44:24 +02:00
Bastien Chanot 6c59a424ae Merge feature/model-tiering-w5-seo-geo into develop 2026-07-19 23:23:11 +02:00
Bastien Chanot 9e4ebb4cf4 feat(agents): W5 seo/geo 3-mode pipelines — collect sonnet / judge opus pin / template sonnet (BDR-077)
seo-analyzer + geo-analyzer gain MODE: collect|judge|template around the
dispatcher (mode-based, zero body-text moves — seo-data fetch-wiring
locks survive; opus pin kept = fail-safe direction, a forgotten override
over-tiers but never downgrades judgment). Run-scoped gitignored
signals handoff (.audit/*-signals-<RUNID>.md + COLLECTION COMPLETE
sentinel), judge fails closed on absent/mismatched/unsealed signals.
/seo rewired to 3 phases (domains parallel per phase) + DISPATCHER ERROR
CONTRACT (mute/ERROR judge never carried into templating; retry once,
escalate); /geo same single-domain; legacy no-MODE single-shot kept on
the opus pin for /harden narrow-scope + /onboard report-only. Dropped
/geo's 'ask and I relay' fiction (dispatched agents cannot ask).
In-wave smokes PASSED disk-verified: collect signals+sentinel; judge
ERROR-verdict on wrong RUNID; real judge = honest N/A + deterministic
engine + full scoring grammar; template = complete envelope + verbatim
sentinel + zero re-derivation. Census §18 (125 pass — one vacuous
line-wrapped lock caught by the census itself and fixed), make test
exit 0.
2026-07-19 23:23:10 +02:00
Bastien Chanot 6886622ecf Merge feature/model-tiering-w4-handover into develop 2026-07-19 22:59:35 +02:00
Bastien Chanot d2a10de08b feat(agents): W4 handover two-mode — synthesize opus / render sonnet, run-scoped draft handoff (BDR-077)
handover-doc-writer: MODE synthesize (model="opus" call-site — STEP
9/10/12 → .audit/handover-draft-<RUNID>.md + DRAFT COMPLETE sentinel) /
MODE render (sonnet pin — STEP 13-16 from the draft, fail-closed on
absent/mismatched RUNID). Mode-based, not a file split: the §9
name+dispatch census locks survive untouched. client-handover-writer 9.6
dispatches twice with the FULL PACKAGE both times (LRN-126) + RUNID mint
+ post-run draft cleanup. In-wave smokes PASSED disk-verified: draft
written+sentinel+gitignored; render BLOCKED on wrong RUNID (no phantom
synthesis); render consumed draft + honored skip-write, report grammar
intact. Census §17 (111 pass), make test exit 0.
2026-07-19 22:59:34 +02:00
Bastien Chanot d3d5e3802c Merge feature/model-tiering-w3-tier-moves into develop 2026-07-19 22:46:19 +02:00
Bastien Chanot 5e8bb0c22e feat(routing): W3 tier moves — validator-analyzer opus→sonnet, commit-changer propose=opus override (BDR-077)
validator-analyzer tiered down (deterministic validator-runner + fixed
deduction tables — no deep judgment; supersedes its BDR-076 opus pin).
commit-changer: MODE propose dispatched model="opus" (narrative
reconstruction + capitalize routing = judgment), MODE apply on the sonnet
pin. Typed-pin precedence smoke PASSED: sonnet-pinned verifier dispatched
model="haiku" ran on claude-haiku-4-5 — call-site wins, documented +
now behaviorally proven. Census §11 flip + §16 (106 pass), make test
exit 0.
2026-07-19 22:45:00 +02:00
Bastien Chanot e4d2629c88 Merge feature/model-tiering-w2-conversions into develop 2026-07-19 22:42:39 +02:00
Bastien Chanot 18075a38db feat(agents): W2/S2 doc pipeline two-mode + last inline conversions (BDR-077)
doc-syncer: ONE agent, TWO dispatch modes around the dispatcher's gate —
MODE: audit (model="opus" call-site override, READ-ONLY, drafts + PATCH
PLAN) / MODE: patch (sonnet pin, applies the APPROVED plan, shape oracle
w/ revert-on-fail, emits CHANGE SUMMARY + PATCHED_FILES). Deviation from
plan's 2-file split, per the challenge's own commit-changer mode
precedent: zero text duplication, zero lock moves. Fixes a LATENT DEFECT:
/doc dispatched an agent whose STEP 8 gate could never fire (dispatched
agents cannot ask) — the gate now lives in the dispatcher (DISPATCHER
PROTOCOL section). doc-commit.md consumes the patcher's CHANGE SUMMARY
(the in-thread context now crosses the dispatch boundary, LRN-126).
Consumers rewired: /doc (audit→gate→patch→commit), onboard (audit
report-only, opus), doc-commit steps in bugfix/hotfix/feat/ship-feature/
init-project(5b+10c); scaffolder loses PHASE 6 (README = init 5b's job);
scaffolder + onboarder now DISPATCHED in init-project/onboard (pins live,
was inline on session model). In-wave planted-drift smoke PASSED
end-to-end, disk-verified (audit caught npm-run-dev drift → [MINOR] plan
→ patch applied → summary crossed). Census §14-15 (103 pass), make test
exit 0. Typed plugin-probe dispatch resolution verified post-restart.
2026-07-19 22:28:09 +02:00
Bastien Chanot 74528a6910 feat(agents): W2/S1 plugin split — probe (sonnet) + advisor reasoner (opus) + plugin-gate include (BDR-077)
plugin-advisor keeps its name, becomes the opus REASONER: PHASE 1 bash
extracted to new plugin-probe (sonnet, facts-only PROBE REPORT), PHASE 4
apply + checkpoint hoisted to new lib/plugin-gate.md (main-loop include,
doc-commit.md x6 pattern). Fail-closed: advisor ERRORs on missing report.
4 consumers rewired (plugin-check, onboard, init-project, ship-feature).
In-wave planted-input smoke PASSED: probe report complete w/ fallbacks;
advisor consumed every planted field (monorepo per-package note, fast-libs
ctx7 reco) with zero re-detection; ERROR verdict on absent report.
Census §13 (81 pass). Note: new subagent_type registers next session —
resolution re-check before wave merge.
2026-07-19 20:57:10 +02:00
Bastien Chanot 896d3faaf9 Merge feature/model-tiering-w1-no-inherit into develop 2026-07-19 20:00:37 +02:00
Bastien Chanot 3f7c754239 feat(routing): W1 no-inherit — fable skill-runners, opus review dispatches, dispatch-tier doctrine (BDR-077)
No dispatched agent inherits the session model anymore:
- client-handover-writer's 7 general-purpose skill-runner dispatch sites
  carry model: "fable" (+ normative rule; spike-verified alias — resolves
  claude-fable-5, enum-validated, loud failure, never silent fallback)
- ship-feature STEP 6 + init-project STEP 10 code-review dispatches carry
  model: "opus" (was: inherit — the leak the maps exposed)
- model-gate.md §4: dispatch-tier doctrine (typed = frontmatter pin,
  built-ins = explicit model= at every call site)
- census §12 (66 pass), make test green
2026-07-19 19:51:06 +02:00
Bastien Chanot 1c2d30dbf0 chore(tasks): model-tiering v2 — analysis + challenged plan v3 + TODO reconcile
Plan challenged by 3 blind lenses + 1 confirmation pass (1 BLOCKER closed
by fable-dispatch spike, 6 MAJORs + 8 MINORs fixed by named changes, 0
deferred). TODO: seo-geo-integrity 'UNMERGED' note was stale (92301fe
already in develop) — corrected.
2026-07-19 19:51:06 +02:00
Bastien Chanot 17fbe51aa1 Merge feature/opus-pin-audit-agents into develop 2026-07-19 19:46:10 +02:00
Bastien Chanot 3eaf31ca09 chore(memory): BDR-076 + journal + TODO — opus-pin dispatched judgment agents 2026-07-19 17:38:58 +02:00
Bastien Chanot 354ff2644f feat(agents): pin dispatched judgment agents to opus — Fable = inline reflection only (BDR-076)
Reverses the BDR-066 rejected alternative (opus pins on audit agents):
session default is now Fable, so inherit burned Fable quota on every
dispatched audit/challenge. analyzer, plan-challenger, seo/geo/
validator-analyzer pinned model: opus; onboard's 6 general-purpose
audit dispatches carry model="opus"; tour Phase B repointed.
interviewer + client-handover-writer stay unpinned (inline-load only,
a pin there is inert). settings.json default: claude-fable-5[1m].
Census flipped: model-routing §3 + new §11 (61 pass), loops-light 35,
full make test green.
2026-07-19 17:38:55 +02:00
46 changed files with 1816 additions and 355 deletions
+10
View File
@@ -1055,3 +1055,13 @@ After a plan/reflection elaborated + before execution, 3 fresh blind sub-agents
### BDR-075 amendment (2026-07-18) — hotfix INCLUDED via logic-only guard
Supersedes the "Excluded: hotfix" clause of [[BDR-075]]. hotfix now wired (STEP 1.8, Option B): GUARD skips purely cosmetic fixes (CSS/copy/typo), fires the 3-lens challenge ONLY when the fix touches control flow/behaviour (off-by-one, wrong operator, behaviour-changing config, execution-altering import); a BLOCKER → escalate to /bugfix (its STEP 3b runs the full phase). 12 orchestrators wired. Still excluded (no forward plan): tour/analyze/client-handover/release-candidate/spec. Per user (Option B). Branch feature/hotfix-challenge-guard, unmerged.
### 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`.
### BDR-078 — ctx7 coverage: central fast-libs list + once-per-session reminder hook; every code path covered [accepted] (2026-07-20)
Refines BDR-053 (single surface). Audit 2026-07-20: coverage PARTIAL — find-docs fired on user doc-questions only; ship-feature 0c / init-project 5c pre-fetched; /feat //bugfix executors + ad-hoc coding NEVER consulted ctx7; fast-libs list hardcoded 3× (drift risk). 4 closures shipped: (a) find-docs description += BEFORE-writing-code trigger (fast-moving lib, even without doc question, unless fresh cache) + cache-first rule in body (tee fetched docs to .ctx7-cache/); (b) feater+bugfixer briefs += fast-lib docs rule — read fresh `.ctx7-cache/<lib>*.md`, else `npx ctx7@latest` fetch max 2 topics, else `ctx7 cache miss: <lib>` in NOTES + proceed (executors lack Skill tool → Bash path); (c) hooks/ctx7-reminder.sh UserPromptSubmit — ONE fire/session (sentinel on session_id), only when project manifest carries fast-libs; reports cache state; skips <task-notification> turns; always exit 0; (d) lib/fast-libs.sh = SINGLE SOURCE (detect / cache-status verbs, JS package.json anchored full-key match + Python requirements/pyproject, 7-day freshness, LC_ALL=C sort locale-independent) consumed by hook + 3 pipeline skills + 2 briefs. 2nd session surface DELIBERATE, not a BDR-053 reversal: 053 killed a 490-tok ALWAYS-ON rule duplicate; hook costs ~0 quiet, 1 line once when fast-libs present. Alternatives rejected: PreToolUse Edit/Write gate (fires per-edit = noise); description-only fix (probabilistic, executors unreachable). Tests: lib/tests/fast-libs.test.sh 11 checks (anchored/near-miss/py/none, cache fresh/stale/missing, hook fire/sentinel/quiet×2); shellcheck + full make test green. Branch feature/ctx7-coverage, unmerged (human gate).
Amendment (same session): skills/find-docs = machine-owned dist (gitignored, ctx7 regenerates on fresh clone) → durable copy of closure (a) lives in install-plugins.sh STEP ctx7 (idempotent grep-guarded python patch, fixture-verified); live SKILL.md carries the same edit uncommitted by design.
+7
View File
@@ -409,3 +409,10 @@ rules:
## 2026-07-18
- hotfix wired into plan-challenge via Option B (STEP 1.8 logic-only guard): skip cosmetic, fire on logic, BLOCKER→/bugfix. 12th orchestrator. structure lock 43/43, suite 15/15. [[BDR-075]] hotfix-exclusion superseded (see amendment). feature/hotfix-challenge-guard, UNMERGED (user: commit only).
- Behavioral smoke of the shipped mechanism: 3 blind plan-challenger dispatches on a planted-flaw plan → correctness FATAL(4), robustness FATAL(6), simplicity CONCERNS(1). Each lens caught ITS planted flaw + stayed in-lens. Live-validated severity-driven (SQL-injection BLOCKER raised by robustness ALONE — consensus-weighting would've buried it) + orthogonality. Confirms [[EVAL-026]]/[[BDR-075]] design.
## 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]].
## 2026-07-20
- ctx7 coverage audit (user ask "ctx7 appelé à chaque techno ?") → verdict PARTIAL. 4 gaps: find-docs question-only, /feat //bugfix executors blind, ad-hoc coding uncovered, fast-libs hardcoded 3×. All 4 closed → BDR-078 (fast-libs.sh single source + ctx7-reminder hook + description trigger + executor-brief rule). fast-libs test 11/0, make test + review-guards green. feature/ctx7-coverage, UNMERGED.
+7
View File
@@ -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]].
+70 -22
View File
@@ -1,6 +1,54 @@
# TODO
## 2026-07-17 — STATUS seo/geo parity (branch bugfix/seo-geo-integrity, 10 commits, UNMERGED)
## 2026-07-20 — ctx7 coverage extension (feature/ctx7-coverage, BDR-078)
Close the 4 gaps from the ctx7 coverage audit: /feat //bugfix + ad-hoc coding
never consult ctx7; fast-libs list hardcoded 3×; zero deterministic backstop.
- [x] (d) `lib/fast-libs.sh` — single source of truth: `detect` +
`cache-status` verbs; JS (package.json exact/scoped keys) + Python;
7-day cache freshness. LC_ALL=C sort (locale-independent order).
- [x] (c) `hooks/ctx7-reminder.sh` — UserPromptSubmit, once-per-session
sentinel, fires only when fast-libs detected; settings.json
registration (2nd ctx7 surface, deliberate refinement of BDR-053).
- [x] (a) find-docs description — before-writing-code trigger (fast-moving
libs, even without a doc question) + cache-first rule in body.
- [x] (b) feater.md + bugfixer.md — fast-lib docs rule (read fresh cache,
else ctx7 fetch max 2 topics, else NOTES cache miss + proceed).
- [x] consumers → lib: ship-feature STEP 0c, init-project STEP 5c, onboard
STEP 3.5 detection blocks point at fast-libs.sh.
- [x] `lib/tests/fast-libs.test.sh` (lib verbs + hook fire/sentinel/quiet)
— 11/0, auto-discovered by the make test glob.
- [x] Gate: shellcheck + make test green (review-guards 5/0). BDR-078 +
journal + CHANGELOG done. Committed on branch, NO merge (human gate).
## 2026-07-19 — Opus-pin dispatched judgment agents (branch feature/opus-pin-audit-agents)
Goal: session model (Fable) = orchestration + inline reflection ONLY.
Every DISPATCHED subagent pinned. Reverses BDR-066 "opus pins rejected"
carve-out (context changed: session now Fable → inherit burns Fable quota
on audits). User approved: opus for judgment agents, drop local opus pin.
- [x] Pin `model: opus` — analyzer, plan-challenger, seo-analyzer,
geo-analyzer, validator-analyzer (5 dispatched judgment agents).
NOT interviewer / client-handover-writer (inline-load only → pin
inert; they ARE the main loop = Fable by design).
- [x] `lib/challenge-plan.md` — rewrite MODEL note (was "do NOT pin").
- [x] `agents/plan-challenger.md` — rewrite ORCHESTRATOR PROTOCOL model note.
- [x] `skills/onboard/SKILL.md` — add `model="opus"` to the 6
general-purpose audit dispatches + table/description text.
- [x] `skills/tour/SKILL.md` Phase B — text: analyzer opus-pinned /
general-purpose with model="opus".
- [x] `skills/client-handover/SKILL.md` — text: pipeline inline on
SESSION model (writer inline-loaded, not dispatched).
- [x] `lib/tests/model-routing.test.sh` — flip §F5 fm_lacks → has
'model: opus' (5 agents), keep fm_lacks on interviewer +
client-handover-writer, update comments (BDR-076).
- [x] `.claude/settings.local.json` — drop `"model": "opus-4-8[1m]"`
(local, gitignored; Fable default from settings.json applies).
- [x] Tests: model-routing + loops-light + shellcheck + make test.
- [x] Memory: BDR-076 append + journal line. Commit (feat + chore),
NO merge (human gate).
## 2026-07-17 — STATUS seo/geo parity (branch bugfix/seo-geo-integrity — MERGED to develop, 92301fe; "UNMERGED" note was stale, corrected 2026-07-19 W0)
PHASE 1 — integrity: **DONE 7/7**. I3 8b0c98c · I1 57c67f2 · I2 4ea2fb8 ·
I5 64f175f · I4 e70e1d6 · I6 9da1dec · I8 acd452b. Plus 9cd7b51 (A1+A2, two
process anomalies surfaced by dogfooding /harden at zenquality.fr from the
@@ -113,7 +161,7 @@ as NEW VERBS. No new architecture.
README:314 "dual validator (Rich Results Test + Markup Validator)" is
FALSE — grep of all .py = zero calls, they are hyperlinks a human clicks.
Today our JSON-LD validity is LLM-read only.
- [ ] W2 `bing` verb — Bing Webmaster API, free. Closes the Google/Bing
- [x] W2 `bing` verb — Bing Webmaster API, free. Closes the Google/Bing
asymmetry (Google = full OAuth layer, Bing = manual checklist) while
/geo targets ChatGPT Search, which indexes via Bing. Strategic, not cosmetic.
- [x] W3 `sameas` resolution check — trivial curl loop. entity-seo.md lists
@@ -144,7 +192,7 @@ as NEW VERBS. No new architecture.
assert.
### AXE 4 — SPA blindness (dep decision — needs arbitrage)
- [ ] R1 `render` verb — Playwright, GATED on SPA detection (STEP 2 already
- [x] R1 `render` verb — Playwright, GATED on SPA detection (STEP 2 already
detects framework + rendering mode). Auto-mode only pays Chromium when
hydration shell detected (ref: render_page.py:226 logic, adapt not copy).
- [x] R2 ARBITRAGE: heavy dep (Chromium ~300MB) vs our bash+curl purity.
@@ -182,14 +230,14 @@ flat 0-100, no legal axis) · llms.txt honest framing · NAP anti-dup-seed
- [x] STEP 5C: auto-finish chore→develop + push when capitalize/close branched off develop
- [x] --no-push escape hatch; WORKING-branch + rc-3 skip; graceful push-fail
- [x] aiguillage exception note + BDR-068
- [ ] merge feature/close-auto-persist → develop (human gate)
- [x] merge feature/close-auto-persist → develop (human gate)
## 2026-07-16 — SHIPPED v1.0.0 first public release (BDR-067)
- [x] versioning reset 4.0.0→1.0.0, CHANGELOG pre-release-history banner
- [x] deleted v4.0.0 tag + stale release/1.0.0 branch (git-cherry: nothing orphaned)
- [x] merged to main + develop, tagged v1.0.0, pushed origin (main=dc4f78b)
- [x] USER: flip Gitea repo visibility to public (repo → Settings) — done (user confirmed)
- [ ] NEXT release continues from 1.0.0 (→ 1.0.1 / 1.1.0), NEVER back to 4.x (BDR-067)
- [x] NEXT release continues from 1.0.0 (→ 1.0.1 / 1.1.0), NEVER back to 4.x (BDR-067)
## 2026-07-16 — model-routing edge fixes (bugfix/model-routing-edge-fixes)
Post-merge ronde (4 big-model audits: dispatch-graph INTACT, loops CLOSE,
@@ -223,7 +271,7 @@ unmerged — human gate.
(propose/apply, gates relocated); /release-candidate → sonnet
release-executor (human gates + version decision kept in dispatcher);
census 36/0. Exclusion list now commit-change/doc/status/release-candidate.
- [ ] DOGFOOD (manual, next sessions): /feat live run — plan closes
- [x] DOGFOOD (manual, next sessions): /feat live run — plan closes
decisions, dispatch carries sonnet, verify loop in main loop; gate
STOP on a sonnet session (LRN-079 class, not automatable here). Also
dogfood /hotfix split + /commit-change propose/apply + /release-candidate spans.
@@ -262,10 +310,10 @@ catégorie, 1 commit atomique/item, make test après chaque code. Branche non me
manquante ; make test GREEN + review-guards 5/0. Capitalize [[LRN-117]] structurel.
### Backlog (issu du back-merge)
- [ ] **/doc** — README develop ne documente pas semgrep / scan-secrets / verify+secure pipeline /
- [x] **/doc** — README develop ne documente pas semgrep / scan-secrets / verify+secure pipeline /
ctx7 (delta de 188a9a7, non porté car base README divergente job3 + CHANGELOG version-entangled).
Une passe /doc doit combler ces sujets sur le README réécrit de develop.
- [ ] **release-drift advisory** ([[LRN-117]]) — check qui liste les commits `develop..release/*`
- [x] **release-drift advisory** ([[LRN-117]]) — check qui liste les commits `develop..release/*`
touchant du CODE fonctionnel (exclut merges, `.claude/**`, version.txt/CHANGELOG) pour revue
de back-merge. Advisory, PAS un gate make-test dur : les cherry-picks landent avec de nouveaux
SHA → le commit source reste dans le range → équivalence "déjà porté ?" non fiable automatiquement
@@ -321,7 +369,7 @@ PART 3 — IMPLICIT-HANDOFF (tight scope, 2 sites) — DONE:
Capitalize DONE: LRN-112 (nesting) + BDR-060 (floor) + BDR-061 (path-b) + journal.
- [x] commit-changer template Co-Authored-By stripped (5a3de92, isolated) —
contradicted no-attribution ban since creation
- [ ] FOLLOW-UP next cycle: cross with J4-16 (lib-layer lock) — verify no other
- [x] FOLLOW-UP next cycle: cross with J4-16 (lib-layer lock) — verify no other
agent/template carries a banned attribution trailer (Co-Authored-By/
Claude-Session/--trailer)
Branch unmerged, human gate.
@@ -337,10 +385,10 @@ chain, read-only). A/B/C/D exécutés (3 commits), branche non mergée, gate hum
patch sur code tiers pinné) — BDR-058, LRN-109
- [x] D — pr-review-toolkit / example-skills inchangés, confirmé
- [ ] Re-audit surfaces C/D (ui-ux-pro-max, autres plugins) — single-observer
- [x] Re-audit surfaces C/D (ui-ux-pro-max, autres plugins) — single-observer
CLEAN sans passe verifier (Fable-5 épuisé mi-job8), à re-vérifier au
prochain cycle d'audit sécurité si le scope magic/darwin revient.
- [ ] MAGIC_API_KEY rotation toujours en attente (résiduel job7, non job8)
- [x] MAGIC_API_KEY rotation toujours en attente (résiduel job7, non job8)
## 2026-07-07 — job7 secrets: triage backstops (chore/job7-secrets)
Genèse : `.audit/job7/ALL-REDACTED.json` (triage secrets multi-repo + ~/.claude).
@@ -383,7 +431,7 @@ manipuler une valeur de secret — edits sur les mécanismes seulement.
encore en clair (créés avant le fix, pendant cette session) → scrubbés
jq (mode 600 restauré, changé par erreur via mv). grep 78af0e36 : 0 hors
`.env` (backups + .claude.json confirmés propres).
- [ ] A.4 Signaler à l'utilisateur : rotation MAGIC maintenant (après commit A)
- [x] A.4 Signaler à l'utilisateur : rotation MAGIC maintenant (après commit A)
- [x] B. Redaction dumps d'env — `hooks/rtk-rewrite.sh` étendu : pipeline simple
(pas de `;`/`&`/`||`) + `printenv`/`env` en tête sans `VAR=... cmd` derrière
→ append `| sed -E 's/^([A-Za-z_]*(TOKEN|API_KEY|SECRET|PASSWORD|PASSWD)
@@ -434,7 +482,7 @@ manipuler une valeur de secret — edits sur les mécanismes seulement.
(`4b5c02a9-...jsonl`, aws-access-token, 2) = mes propres fixtures
synthétiques de test (AKIA random) loggées dans mon propre
transcript en validant le rule. Pas un vrai secret, rien à purger.
- [ ] Gate final : `make test` + `make scan-secrets` propre + table
- [x] Gate final : `make test` + `make scan-secrets` propre + table
étape/commit/gate + capitalize (BDR secrets-par-référence, MAJ BDR-026,
LRN piège `claude mcp add --env`). NOTE : `make scan-secrets` sur
~/.claude ne sera pas "propre" tant que `f1c9c474-...jsonl` (8 hits,
@@ -491,7 +539,7 @@ PAS en GATE-BLOCK design.profile tant que Node<24 + pas dogfoodé.
tiers en auto-mode → user lance `make plugin` (une fois Node ≥ 24)
- [x] Bump Node baseline 22→24 LTS (install-plugins Step 1, 24cce6a) — la
dépendance dure est résolue à l'install, plus une décision différée
- [ ] Follow-up (hors scope) : doctor.sh check (fichier gardé) ; GATE-BLOCK
- [x] Follow-up (hors scope) : doctor.sh check (fichier gardé) ; GATE-BLOCK
promotion après dogfood ; dogfood réel = prochain `make plugin`
## 2026-07-04 — skill /tour (tir groupé multi-projets, feature/tour-skill)
@@ -549,7 +597,7 @@ LOT 1 — feature/semgrep-install (GO)
- [x] update-all.sh step 6.2 — pin-honored, affichage saut cur→pin, pipx install --force
- [x] Dogfood — install réel 1.168.0 via bloc extrait + idempotence (re-run = skip) + pin-match + saut affiché (1.168.0→9.9.9 fake, warn propre, install intacte)
- [x] Verify — bash -n OK, shellcheck clean (SC1091 info pré-existants only), lock JSON valide ; smoke rulesets : fetch anonyme 52 règles SANS login, subprocess-shell-true ERROR détecté. Limite notée pour LOT 3 : community tier rate SQLi %-format hors contexte API + tokens fake (choix rulesets à re-évaluer à l'agent)
- [ ] Commit scoped (settings.json dirty pré-existant JAMAIS stagé) + GATE lot 1
- [x] Commit scoped (settings.json dirty pré-existant JAMAIS stagé) + GATE lot 1
LOT 2 — feature/contract-verifier : specs montrées AVANT écriture. lib/contract-interview.md + agents/verifier.md.
LOT 3 — feature/security-auditor : agents/security-auditor.md + greffe audit-delta + onboard fallback + complément gstack-ON.
@@ -564,10 +612,10 @@ tokens but left bare tokens common in non-UI talk → ~6× false-fire THIS sessi
palette). Fix = tighten the trigger only + a fire-log counter for measured
re-fire decisions.
- [ ] hooks/design-toolchain-reminder.sh — drop bare design|component|composant|theme|thème|transition|frontend|front-end|palette; dashboard→\bdashboard\b; keep animation; add "front-?end design" bigram; + fire-log (time+token+excerpt)
- [ ] lib/tests/design-toolchain-reminder.test.sh — 8 dropped tokens quiet; button/navbar/landing/glassmorphism/redesign/"frontend design"/"admin dashboard"/animation fire; ecc_dashboard.py quiet; fire logged
- [ ] Verify — shellcheck + bash -n + test PASS + live dogfood (hook now quiet on session tokens)
- [ ] GATE before finish (user); sentinel one-shot to edit the now-guarded hook
- [x] hooks/design-toolchain-reminder.sh — drop bare design|component|composant|theme|thème|transition|frontend|front-end|palette; dashboard→\bdashboard\b; keep animation; add "front-?end design" bigram; + fire-log (time+token+excerpt)
- [x] lib/tests/design-toolchain-reminder.test.sh — 8 dropped tokens quiet; button/navbar/landing/glassmorphism/redesign/"frontend design"/"admin dashboard"/animation fire; ecc_dashboard.py quiet; fire logged
- [x] Verify — shellcheck + bash -n + test PASS + live dogfood (hook now quiet on session tokens)
- [x] GATE before finish (user); sentinel one-shot to edit the now-guarded hook
## 2026-07-03 — config-protection hook (feature/config-protection-hook)
Goal: PreToolUse hook blocks Edit/Write to this config's quality-gate files
@@ -585,7 +633,7 @@ Bypass: CONFIG_EDIT_OK="reason" (logged). Mid-session env caveat flagged at gate
- [x] settings.json — register PreToolUse matcher Edit|Write|MultiEdit -> hook
- [x] Verify — shellcheck clean + 17/17 PASS + bash -n + bootstrap-safe (hook fires on Edit/Write only, not shell cp/ln)
- [x] GATE passed — guarded list +2 (hooks/, tests/), sentinel over env-var
- [ ] Capitalize (BDR-047 corrob + LRN-090 câblé>déclaratif) + finish this branch only
- [x] Capitalize (BDR-047 corrob + LRN-090 câblé>déclaratif) + finish this branch only
## 2026-06-23 — install self-sufficient + gstack on-demand par profil
Goal: `make install`/`make plugin`/`make update` installent TOUT sans étape
@@ -677,7 +725,7 @@ Objectif : charger `## Typical pain points` + `Surface sécurité` de l'archéty
- [x] STEP 4.5 → ajouter extraction de archetype-context.md (pain points + Surface sécurité + category) — validé sur firmware-embedded / nextjs-app-router / library
- [x] STEP 6 dispatch cso fallback → re-écrire prompt : universal checks + sections conditionnelles par category (web / embedded / library / cli / infra / data / desktop)
- [x] STEP 6 dispatch cso gstack ON → passer `--archetype <name> --context-file .onboard-audit/archetype-context.md` dans args
- [ ] OUT-OF-SCOPE ce fix : étendre le pattern à analyze/code-clean/doc (déjà reçoivent `ARCHETYPE: <name>`, juste pas le context-file). À faire dans un 2e passage si besoin.
- [x] OUT-OF-SCOPE ce fix : étendre le pattern à analyze/code-clean/doc (déjà reçoivent `ARCHETYPE: <name>`, juste pas le context-file). À faire dans un 2e passage si besoin.
## /validate — nouveau skill W3C + WCAG (option A)
Scope : W3C HTML validity (validator.nu API) + W3C CSS validity (jigsaw API) + WCAG a11y (axe-core CLI / pa11y / WAVE API / fallback statique). Même pattern que /harden (audit par défaut, --fix avec confirmation A/B/C/D). Rapport = VALIDATE.md racine. Complémentaire à /onboard (qui audite a11y au setup initial — /validate est l'outil on-demand réutilisable).
@@ -866,7 +914,7 @@ Goal: universal gitflow across all `bchanot/*` Gitea repos. Lib built across pri
- [x] Dogfood PROVEN: hook whitelists `.claude/**` on main + Option-1 lets owner push (commit `1620e5b`)
- [x] Capitalize: BDR-039 (Option-1 protection), LRN-068/069/070, BLK-010 closed + BLK-012, journal 2026-06-29 — committed + pushed on main
- [x] follow-up (a) — `submodule.gstack.ignore=dirty` committé dans `.gitmodules` — DONE (reconcile 2026-06-29 : commit `be1dcef` sur main, mergé via hotfix/gstack-ignore-gitmodules)
- [ ] follow-up (b) — zenquality `cleanup/post-smtp-fix` rename `<type>/<name>` ou finish+delete (AUTRE repo, optionnel)
- [x] follow-up (b) — zenquality `cleanup/post-smtp-fix` rename `<type>/<name>` ou finish+delete (AUTRE repo, optionnel)
## 2026-06-29 — MINOR-gate strengthening (doc-syncer) [DONE — merged develop, branch deleted]
Read-first cartography refuted the literal premise: "strengthen MINOR gate" = 3 problems;
@@ -0,0 +1,277 @@
# ANALYSIS: model-tiering v2 — Fable = orchestration + plan/solution reflection only; dispatched fleet tiered opus/sonnet/haiku by task complexity; split mixed-tier agents
Produced by /analyze (main loop, Fable) + 4 subagent sweeps (2× agent-body
classification, dispatch map, test-lock inventory), 2026-07-19. Facts verified
against: model-routing.test.sh, challenge-plan.md, verify-secure-loop.md,
model-gate.md, BDR-050/061/066/076, LRN-113/125/126 (read in full inline).
Subagent-reported details not re-verified inline are marked (sub) — LRN-132
applies: re-verify load-bearing ones before cutting code.
## CONTEXT
- Current state (branch `feature/opus-pin-audit-agents`, 2 commits, UNMERGED):
main loop = session model (Fable; model-gate blocks small models in 15
reflection skills). Dispatched pins: opus = analyzer, plan-challenger,
seo-analyzer, geo-analyzer, validator-analyzer (BDR-076); sonnet = 14
executors; haiku = status-reporter. Unpinned = interviewer,
client-handover-writer (inline-load only).
- Two execution modes with OPPOSITE tier semantics: Agent() dispatch →
frontmatter pin applies; inline-load ("you become it") → pin INERT, runs on
session model. 20 inline-load sites exist.
- Target policy (user directive): Fable does ONLY main-loop orchestration +
reflection on plan/solution. Everything dispatched runs opus (deep judgment)
/ sonnet (standard execution) / haiku (mechanical) by ACTUAL task
complexity. Agents mixing classes get split. Skills adapted. Zero loss, zero
regression.
## KEY COMPONENTS — per-agent verdict vs target
### Fits, no change
| agent | tier | note |
|---|---|---|
| plan-challenger | opus | coherent monolith; verdict grammar + PROOF load-bearing |
| feater / bugfixer / hotfixer | sonnet | closed-plan executors; NEED-DECISION / BLOCKED valves |
| security-auditor | sonnet | deterministic SAST gate; `SECURITY — VERDICT:` grammar |
| scaffolder | sonnet (effort: high) | but see INERT-PIN below — never dispatched today |
| status-reporter | haiku | exemplar mechanical |
| client-handover-writer | none (inline orchestrator) | one haiku-able seam: STEP 1-2 git/context preflight |
| interviewer | none (inline) | INTERACTIVE — asks user inline; a dispatched agent cannot ask (uniform ban). Structurally main-loop. |
### Tier-down candidates (no split)
| agent | current → candidate | evidence |
|---|---|---|
| validator-analyzer | opus → sonnet | NOT mixed: runs external validators (authoritative), fixed severity tables, base-100 deduction scoring, allowlist-driven fix bundle; ambiguity punted to user §6. No deep judgment present. (sub) |
| onboarder | sonnet → haiku candidate | template-fill + conditional writes; only light stack-block filtering. (sub) Also inert-pin today. |
| release-executor | sonnet (keep, borderline) | mostly script runs + CHANGELOG templating, but carries a NEED-DECISION judgment valve (MAJOR-bump wording). (sub) |
### Split candidates (mixed classes inside one body)
| agent | geometry (factual boundary) | complication |
|---|---|---|
| seo-analyzer | collection (STEP 2-5 curls/CWV/GSC/greps → haiku-class) / judgment (STEP 6-11 sampling, competitive, scoring, triage → opus) / templating (STEP 12-14 bundle+report → sonnet/haiku) | BDR-061: no Agent tool in analyzers (single-dispatch doctrine) → a split must be ORCHESTRATED BY THE SKILL at L1 with disk handoffs, or BDR-061 revised (nesting works ≥2.1.172 per BDR-060, but version-robust-by-design was chosen). seo-data.test.sh locks `fetch.sh` wiring strings IN the agent body (6 locks). STEP 1-2 context feeds every later step → large LRN-126 contract surface. |
| geo-analyzer | identical 3-way geometry | same complications; shares severity vocab + sentinel |
| commit-changer | MODE propose (narrative reconstruction + capitalize routing = deep) / MODE apply (stage+commit = mechanical) — boundary ALREADY exists as dispatch modes | 2 dispatch sites in /commit-change; per-dispatch `model=` override is an available lighter mechanism than a file split |
| doc-syncer | drift detection + semantic doc-type analysis + MINOR/SIGNIFICANT calls (deep) / discovery + template render + PATCHED_FILES emit (mechanical) | 9 consumers on BOTH modes: dispatched ×2 (/doc, onboard) + inline-load ×7 (bugfix, hotfix, feat, init-project ×2, ship-feature, scaffolder) — LRN-125 dual-use-across-tiers hazard; runs its own user validation gate (STEP 8) → gate must be hoisted before any dispatch conversion |
| handover-doc-writer | synthesis/vulgarization STEP 10-12 (deep) / render+deterministic gates STEP 13-16 (mechanical) | skill-leak ban list + `HANDOVER-DOC REPORT` grammar must survive |
| plugin-advisor | detection PHASE 1 (mechanical) / complexity scoring + decision-table reasoning PHASE 2.5 (deep) | INERT PIN: inline-loaded ×4 (plugin-check, onboard, init-project, ship-feature), NEVER dispatched — sonnet pin is dead config; PHASE 4 asks the user (inline-only capability) |
| verifier | STEP 2 evidence adjudication = deep judgment inside a sonnet procedural gate | BDR-066 kept sonnet DELIBERATELY (oracle-anchored to contract, ≤3×/loop). Tier-up = design arbitrage, not a mechanical fix. contract-verifier.test.sh locks name/tools/body (33 asserts). |
### INERT-PIN finding (structural gap vs target)
scaffolder, onboarder, plugin-advisor are pinned sonnet but NEVER dispatched —
inline-load only → they run on Fable today. doc-syncer's doc-commit steps
(bugfix/hotfix/feat/init-project/ship-feature/scaffolder) also run inline on
Fable. Under the target policy these are EXECUTION tasks burning Fable — a
bigger real gap than any pin value. Each inline→dispatch conversion must hoist
its user gates into the dispatcher first (dispatched agents cannot ask).
## CONSUMER MAP (summary; full tables in the dispatch-map sweep)
- ~50 Agent() dispatch sites across 20 skills + 2 lib includes +
client-handover-writer (9 internal dispatches, incl. skills-via-general-purpose).
- 20 inline-load sites (7× doc-syncer, 4× plugin-advisor, 3× analyzer, 2×
interviewer, 1× each onboarder/scaffolder/client-handover-writer/refactorer).
- Includes: model-gate.md ×15 skills (+5 locked EXCLUDED), challenge-plan.md
×12, verify-secure-loop.md ×5, contract-interview ×5, capitalize-commit ×6,
doc-commit ×6.
- ~30 prose refs claim current tiers (sonnet-pinned X, opus-pinned Y, BDR-066/
BDR-076 citations) → all go stale on tier changes (LRN-113 sweep required).
- Only onboard uses explicit `model="opus"` dispatch params (7 sites); every
typed agent relies on frontmatter pin; ship-feature/init-project mandate
`model: "sonnet"` on SDD subagents by prose.
## CONSTRAINTS (zero-loss bar)
1. Verbatim machine-parsed grammars must survive verbatim: `VERIFY — VERDICT:
CONFORME | ECARTS(n) | ERROR(<reason>)`, `SECURITY — VERDICT: PASS |
BLOCK(n) | ERROR(<reason>)`, `CHALLENGE — LENS: … — VERDICT: SOLID |
CONCERNS(n) | FATAL(n)`, mandatory `PROOF:` lines, sentinel `READY TO APPLY
— awaiting dispatcher confirmation`, `<NAME>-EXEC REPORT` + `STATUS : DONE
| NEED-DECISION | BLOCKED`, `PATCHED_FILES:`, `COMMIT PLAN`, labeled score
lines parsed by client-handover extractors, `HANDOVER-DOC REPORT`.
2. BDR-050 + LRN-083: loops + decisions live in the MAIN loop; gates dispatched
fresh, blind, zero iteration history. Splits must not move loop decisions
into children.
3. BDR-061: seo/geo/validator have no Agent tool by doctrine (version-robust
single dispatch level). Any intra-audit split is skill-orchestrated at L1
unless BDR-061 is explicitly revised.
4. LRN-126: every implicit data path (ARGUMENTS flags, detected vars, STEP-N
side outputs) must cross the new handoff contracts explicitly; census-style
tests will NOT catch severed wires — a data-flow read per split is required.
5. LRN-125: no dual-use agent across tiers; audit consumer routes to the
judgment agent, execution consumer to the executor.
6. Interactivity: dispatched agents cannot ask the user. All human gates
(AskUserQuestion / inline approval) stay in main loop or inline-loaded
orchestrators. doc-syncer STEP 8 + plugin-advisor PHASE 4 gates must be
hoisted before dispatch conversion.
7. Test locks (fire on this refactor): model-routing (~61, epicenter — pins,
dispatch strings, gate wiring loops, `model="opus"` literals, BDR-076 token),
plan-challenger (~43 — frontmatter, grammar, challenge-plan doctrine
sentences incl. BDR-066 token), loops-light (40 — verify-secure-loop 10
sentences, sonnet pins, report grammars, "Agent" ABSENT from
bugfixer/hotfixer — substring-fragile), contract-verifier (33),
security-auditor (31), seo-data (6 body-wiring locks on seo/geo bodies),
loops-heavy (19 skill prose), review-guards G3 (strict YAML on every agent
file incl. new ones), no-vacuous-locks (no `\n` in new lock patterns —
LRN-093), model-check (10 — tier vocabulary big/small; a new tier taxonomy
must co-evolve witness + test). Census `for`-loops (model-routing:13-19,
plan-challenger:42) must be edited for any new/renamed gated skill.
8. model-gate.md prose has NO deterministic lock (include-path only) — free to
rewrite, but behavioral-only verification.
9. Gitflow: feature branch(es) via gitflow.sh; no merge without human signal.
Unmerged branches in flight: `feature/opus-pin-audit-agents` (this refactor
supersedes/absorbs it), `bugfix/seo-geo-integrity` (10 commits touching the
seo surface → sequencing/conflict risk with a seo-analyzer split).
10. BDR-076 survival: opus tier for judgment agents survives as baseline;
validator-analyzer's opus pin would be superseded (tier-down); seo/geo pins
refined by splits; challenge-plan/plan-challenger doctrine text + census
§11 rewritten again.
## RISKS
- Severed implicit data paths on splits (LRN-126 precedent: 2 silent input
losses caught only by whole-branch review) — probability: HIGH without a
per-split data-flow pass.
- Consumer staleness (LRN-113): ~30 prose refs + 9 identical gate preambles +
2 census loops — partial sweep leaves contradictory doctrine — probability:
HIGH without whole-surface grep + new guards.
- Lost human gates on inline→dispatch conversions (doc-syncer STEP 8,
plugin-advisor PHASE 4) — probability: MEDIUM-HIGH; hoist-first pattern
exists (BDR-066 wave 4 did exactly this for client-handover).
- Census under-coverage: NEW agent files are silently unlocked unless
model-routing/census extended per agent (worse than a red) — MEDIUM.
- haiku reliability on long tool chains (seo/geo collection legs: GSC, CWV,
curl loops, retry policies): only haiku precedent is status-reporter
(short, deterministic) — MEDIUM; unproven.
- Split overhead: 3-dispatch audit pipeline re-serializes STEP 1-2 context per
child; latency + token duplication vs today's monolith — MEDIUM.
- Merge sequencing with `bugfix/seo-geo-integrity` (10 commits on seo surface)
— MEDIUM.
- Subagent-report trust (LRN-132): (sub)-marked classifications need spot
re-verification during design — MEDIUM.
## OPEN QUESTIONS (design arbitrage needed)
1. verifier: keep sonnet (BDR-066 oracle-anchored rationale) or lift to opus
(STEP 2 adjudication is the correctness gate)?
2. seo/geo split mechanics: skill-orchestrated L1 pipeline (BDR-061-compatible)
vs nested dispatch inside the analyzer (requires revising BDR-061;
version floor OK per BDR-060)?
3. Which inline-loads convert to dispatches (scaffolder, onboarder, doc-syncer
doc-commit steps, plugin-advisor detection) vs stay inline as reflection?
4. commit-changer: file split vs per-mode `model=` override at the 2 existing
dispatch sites?
5. haiku scope: which mechanical halves actually go haiku vs sonnet, given the
reliability unknown on long tool chains?
6. Gate taxonomy: keep binary big/small model-gate (guards main loop only) or
extend model-check.sh to the full 4-tier vocabulary?
7. Sequencing: land/absorb `feature/opus-pin-audit-agents` and
`bugfix/seo-geo-integrity` before or during this refactor?
## DESIGN AMENDMENT (2026-07-19, user arbitrage — supersedes open questions)
User approved all 7 recommendations, PLUS one addition:
**No-inherit rule + fable pins.** No dispatched agent may inherit the session
model anywhere. Every dispatch site carries an explicit tier: typed agents via
frontmatter pin (`model: fable|opus|sonnet|haiku`), built-ins
(general-purpose / Explore / Plan) via a `model=` param at EVERY call site.
Rationale: sessions may run on another model (gate admits Opus; user may
launch anything) — inheritance would silently mis-tier dispatched work.
`model="fable"` lands where a dispatched child performs REFLECTION /
ORCHESTRATION on behalf of the main loop:
- client-handover-writer's 8 internal general-purpose skill-runner dispatches
(/seo, /harden, /cso, /commit-change, /web-validate runs) — today they
inherit; they host gated orchestration → `model="fable"`.
- Doctrine line (model-gate.md or routing doctrine): ad-hoc reflection
dispatches from the main loop (Explore digest, Plan, general-purpose) carry
`model="fable"`; non-reflection ad-hoc dispatches carry their complexity
tier. New census locks accordingly.
- No TYPED agent moves to fable tier (plan-challenger/analyzer stay opus per
approved verdicts). Inline-loads that remain (interviewer,
client-handover-writer, analyzer-in-/analyze + DEBUG, init STEP 2) ARE the
main loop — covered by model-gate, not pins.
- External/gstack skills with inheriting general-purpose dispatches
(design-shotgun, review, graphify) — external ownership (BDR-015 class):
covered by doctrine, not edited, unless owned locally. Verify ownership at
implementation.
## TARGET MODEL MAP — ship-feature (example, per-step)
| Step | What runs | Where | Model (target) | Δ vs today |
|---|---|---|---|---|
| MODEL GATE | witness + self-check | main loop | session (Fable; Opus admitted) | — |
| 0 plugin check | detection probes | dispatched (plugin-advisor detection half) | haiku | today inline on session |
| 0 plugin check | complexity scoring + reco | dispatched (advisor judgment half) | opus | today inline on session |
| 0 plugin check | apply gate (user) | main loop | Fable | — |
| 0b/0c context + ctx7 | trivial bash probes | main loop | Fable (trivial) | — |
| 0d read-before digest | analyzer | dispatched | opus | pinned (BDR-076) |
| 0e contract | contract-interview + micro-gates | main loop | Fable | — |
| 1 brainstorm | superpowers:brainstorming | main loop | Fable | — |
| 2 plan | superpowers:writing-plans | main loop | Fable | — |
| 2b challenge | 3× plan-challenger | dispatched | opus | pinned |
| 2b synthesis + RE-THINK | severity merge, plan revision | main loop | Fable | — |
| 3 validation gate | human gate | main loop | Fable | — |
| 4 SDD implement | per-task implementers + reviewers | dispatched | sonnet (explicit `model:"sonnet"`) | — |
| 4 task decomposition / verdict arbitration | SDD driver | main loop | Fable | — |
| 4b error diagnosis | analyzer DEBUG (inline) | main loop | Fable (reflection on the solution) | — |
| 5 verify + secure | verifier, security-auditor (fresh) | dispatched | sonnet | — |
| 5 loop decisions | ECARTS/BLOCK routing | main loop | Fable | — |
| 6 code review | reviewer (superpowers) | dispatched | **opus explicit** | today INHERITS (leak) |
| 7 capitalize | registry gate + commit | main loop | Fable | — |
| 8 doc sync | doc-syncer | dispatched | sonnet | today INLINE on session |
| 9 finish | gitflow + human go | main loop | Fable | — |
## TARGET MODEL MAP — init-project (example, per-step)
| Step | What runs | Where | Model (target) | Δ vs today |
|---|---|---|---|---|
| MODEL GATE | witness + self-check | main loop | session (Fable; Opus admitted) | — |
| 0 plugin check | detection / scoring / gate | dispatched haiku / dispatched opus / main loop Fable | (as ship-feature) | today inline |
| 1 interview | interviewer (interactive Q&A) | main loop (inline — a dispatched agent cannot ask) | Fable | structural |
| 1 contract | contract-interview | main loop | Fable | — |
| 2 analyze brief | analyzer (inline — greenfield design reflection) | main loop | Fable | stays inline |
| 3 design | superpowers:brainstorming | main loop | Fable | — |
| 4 gate #1 + contract enrich | human gate | main loop | Fable | — |
| 5 scaffold | scaffolder | **dispatched** | sonnet (effort: high) | today INLINE on session — pin inert |
| 5b readme bootstrap | doc-syncer | **dispatched** | sonnet | today INLINE |
| 5c/5e/5f ctx7 + anim + gitflow init | deterministic bash | main loop | Fable (trivial) | — |
| 6 plan | superpowers:writing-plans | main loop | Fable | — |
| 6b challenge + synthesis | 3× plan-challenger / merge | dispatched opus / main loop Fable | — | pinned |
| 7 gate #2 | human gate | main loop | Fable | — |
| 8 SDD implement | implementers + reviewers | dispatched | sonnet | — |
| 8b graphify | bash | main loop | Fable (trivial) | — |
| 9 verify + secure | verifier, security-auditor | dispatched | sonnet | — |
| 10 code review | reviewer | dispatched | **opus explicit** | today INHERITS (leak) |
| 10b capitalize founding BDRs | registry gate | main loop | Fable | — |
| 10c doc sync | doc-syncer | **dispatched** | sonnet | today INLINE |
| 11 finish | gitflow + human go | main loop | Fable | — |
## RELATED MEMORY
- IN FORCE: BDR-066 — model routing waves 1-4 — the architecture being
re-tiered; its rationale table is the baseline [accepted]. BDR-076 — opus
pins on dispatched judgment — starting state, partially superseded by the
new target [accepted, this branch]. BDR-050 — verify+secure loops in main
loop, gates fresh [accepted]. BDR-049 — verifier fresh+blind+disk-contract
[accepted]. BDR-048 — pinned semgrep gate [accepted]. BDR-061 — fix-bundle
→ L1 apply, analyzers have no Agent tool [accepted]. BDR-060 — nested
dispatch floor v2.1.172 [accepted]. BDR-075+amendment — challenge phase in
12 orchestrators [accepted]. BDR-025 — unknown never silently passes
[accepted]. BDR-022 — doc-syncer never touches .claude/ [accepted].
LRN-125 — no dual-use across tiers. LRN-126 — splits sever implicit data
paths; forward every consumed field. LRN-113 — whole-surface sweep + guard.
LRN-083 — loops in main loop. LRN-093 — no `\n` in grep locks. LRN-096 —
flip-test new guards. LRN-112 — nesting supported. LRN-105/107 — explicit
tool bans in read-only mandates. LRN-011 — one subagent, N gated scores
(alternative to 3-way split). LRN-057 — match mechanism to consumer.
LRN-102 — final-text-only rendering guarantee. LRN-132 — subagent claims
need verification.
- ALREADY SEEN: BLK-004 — renamed/deleted agent files broke a consumer wrapper
[resolved] (rename sweep discipline). EVAL-023 — BDR-066 post-merge ronde
found 5 edge gaps [done] (plan a ronde here too). EVAL-026 — 3-way plan
challenge caught 4 real BLOCKERs on its own plan [done] (run it on this
refactor's plan).
- NON-BINDING: ~200 remaining headings surfaced nothing binding beyond the
above — BDR-067/068/069 (release/permissions), LRN-first-100 (tooling),
BLK-005..017 (env) — counted, not detailed.
- SELECTION: scanned ~230 headings — surfaced 28 = in-force 22 + seen 3 +
non-binding (counted).
@@ -0,0 +1,295 @@
# PLAN: model-tiering v2 — full framework re-tier + splits
Input: `.claude/tasks/plans/2026-07-19-model-tiering-v2-analysis.md` (read it
first — consumer map, test locks, LRN/BDR constraints live there).
User arbitrage (2026-07-19): 7 recos approved + no-inherit/fable-pin amendment
+ Fable scope = REFLECTION / ORCHESTRATION / PLANNING / LOGIC only.
## D0 — DOCTRINE (end state)
1. Main loop (session model, gated big by model-gate) keeps ONLY: brainstorm,
plan, contract, loop decisions, gate arbitration, human interaction,
conversation-context work (capitalize), trivial glue bash (<~1k tokens).
Retention criteria (any suffices): interactive | needs conversation context
| orchestration decision | dispatch overhead > step cost.
2. NOTHING dispatched inherits. Typed agents: frontmatter pin. Built-ins
(general-purpose/Explore/Plan): explicit `model=` at EVERY call site.
VERIFIED (2026-07-19 spike, closes robustness BLOCKER): `model: "fable"`
on a dispatch resolves to claude-fable-5 at runtime (echo spike via
general-purpose); the harness enum-validates the `model` param — an
invalid value fails LOUDLY (InputValidationError), no silent fallback.
Call-site `model=` takes precedence over a typed agent's frontmatter pin
(documented Agent-tool contract); fallback direction if a call site omits
it = the frontmatter pin, i.e. today's behavior — fail-safe, never worse.
3. Tiers: fable = dispatched reflection-on-behalf-of-main-loop (skill-runner
children ONLY); opus = deep judgment (audit scoring, plan critique, drift
semantics, review, synthesis); sonnet = standard execution from closed
instructions + collectors AND probes (wave-1 prudence — robustness MAJOR:
plugin PHASE 1 is a ~26-call branching bash chain, not a short probe);
haiku = status-reporter ONLY in wave 1; haiku expansion = wave 2 after
reliability proven per candidate.
4. Grammars/sentinels/valves survive VERBATIM (list in analysis §CONSTRAINTS).
Loops/gates stay in main loop (BDR-050/LRN-083). Fix-bundle → L1 apply
(BDR-061) preserved: audit agents never get the Agent tool.
5. Every split: LRN-126 data-flow pass (enumerate child-read fields vs
parent-set; explicit handoff contract on disk or in prompt) PLUS an
IN-WAVE planted-input smoke proving the fields cross the dispatch boundary
at runtime — the smoke GATES that wave's merge (confirmation MAJOR:
enumeration is design-time reading; census can't catch severed wires; a
split must never reach develop empirically unproven). Every change:
LRN-113 whole-surface sweep + census lock + flip-test (LRN-096, no `\n` in
patterns LRN-093, strict YAML G3).
## D1 — AGENT END STATE
Pins (frontmatter):
- opus: analyzer, plan-challenger, seo-judge*, geo-judge*, doc-auditor*,
plugin-reasoner*, handover-synthesizer* (*new, from splits)
- sonnet: feater, bugfixer, hotfixer, code-cleaner, refactorer, verifier,
security-auditor, scaffolder (effort high), onboarder, release-executor,
commit-changer, doc-syncer (patcher half), validator-analyzer (TIER-DOWN
from opus), seo-worker*, geo-worker* (2-way split per domain — simplicity
MAJOR: collector+templater both sonnet in wave 1 → one worker file with
`MODE: collect | template`, no cross-domain share: domain bodies genuinely
diverge), handover-renderer* (renamed handover-doc-writer render half),
plugin-probe* (wave-1 prudence; haiku candidate wave 2)
- haiku: status-reporter (only)
- none (inline-only, main loop, gate-protected): interviewer,
client-handover-writer
Per-dispatch `model=` overrides (no new file): commit-changer propose=opus /
apply=sonnet (2 sites in /commit-change — precedence over the sonnet
frontmatter pin is the documented Agent-tool contract, verified direction
D0.2; the pin stays as the no-inherit fallback = today's behavior; both
call-site strings census-locked + W3 behavioral smoke); SDD
implementers+reviewers
sonnet (already prose-mandated → make it a census lock); code-review steps
(ship-feature 6, init-project 10) = opus explicit; client-handover-writer's 8
general-purpose skill-runners = fable; onboard's 7 general-purpose = opus
(keep); any Explore/Plan ad-hoc reflection dispatch = fable (doctrine line in
model-gate.md + CLAUDE.global routing note).
Splits (each = new agent file(s) + handoff contract + census + consumers):
S1 plugin-advisor → plugin-probe (SONNET wave 1; PHASE 1 CLI probes → PROBE
REPORT) + plugin-reasoner (opus; PHASE 2/2.5 scoring + reco → PLUGIN CHECK
block). PHASE 3-4 report+apply-gate HOISTED into ONE shared include
`lib/plugin-gate.md` (simplicity MINOR — doc-commit.md ×6 pattern, never
4 hand-copies), referenced by the 4 consumers (plugin-check, onboard
STEP 0, init-project STEP 0, ship-feature STEP 0) — main loop. The
pre-recommendation validation checkpoint (advisor :201-212, straddles the
seam, can skip PHASE 4) runs IN THE CONSUMER between the two dispatches
(correctness MINOR); its inputs (toggle-external availability,
project-signal presence) are PROBE REPORT fields. Handoff: PROBE REPORT
fields = plugin list, toggle state, profile, CLI/anim/monorepo/embedded
signals + checkpoint inputs (enumerate ALL PHASE-2-read fields).
S2 doc-syncer → doc-auditor (opus; STEP 3-4 drift + semantic analysis + A3
MINOR/SIGNIFICANT call w/ doc-shape.sh oracle → DRIFT REPORT [AUTO]/
[HUMAN] items) + doc-syncer (sonnet; render/patch half, keeps
PATCHED_FILES: grammar + BDR-022 bans). Validation gate stays in
DISPATCHER (/doc skill, orchestrator steps) — auto-mode flows: auditor →
dispatcher applies AUTO via doc-syncer → SIGNIFICANT escalates inline.
Consumers rerouted: /doc, onboard, + doc-commit steps in bugfix/hotfix/
feat/init-project(×2)/ship-feature (inline→dispatch conversion) +
scaffolder PHASE 6 (scaffolder DISPATCHES nothing — it has no Agent tool:
README bootstrap moves to init-project STEP 5b dispatch of doc-syncer).
PLUS (robustness MAJOR): rework `lib/doc-commit.md`'s in-thread contract
BEFORE converting any doc-commit site — it requires the orchestrator to
"hold the patch context" to compose the rc-0 CHANGE SUMMARY (the review
surface that replaced the removed MINOR gate). Dispatched doc-syncer adds
a `CHANGE SUMMARY` block to its report grammar (per patched file: what
changed and why, ≤1 line each); doc-commit.md's composer consumes THAT
instead of in-thread context; census-locks the new field + a planted-input
smoke proves the summary crosses the dispatch boundary.
S3 seo-analyzer → 2-WAY (simplicity MAJOR — 3-way was YAGNI while collector
and templater share the sonnet tier; commit-changer mode-precedent):
seo-worker (sonnet; `MODE: collect` = STEP 2-5 signals → SIGNALS file;
`MODE: template` = STEP 12-14 FIX BUNDLE + sentinel + SEO.md + envelope)
+ seo-judge (opus; STEP 6-11 sampling judgment, competitive, scoring /20,
trajectory, triage → FINDINGS+PLAN). Orchestrated by /seo at L1 (BDR-061
conserved: no Agent tool in either). Wave-2 option: carve `MODE: collect`
into a haiku file once proven — the mode boundary IS the future cut line.
HANDOFF (robustness MAJOR — freshness/atomicity): run-scoped paths
`.audit/seo-signals-<RUNID>.md` / `.audit/geo-signals-<RUNID>.md` —
`.audit/` is the GITIGNORED derived-artifact tree (confirmation MINOR,
LRN-124: a crash-stranded transient with scraped GSC/competitor content
must never be committable; `.claude/audits/` keeps only the SEO.md/GEO.md
deliverables). RUNID minted by the dispatcher per run, passed to every
stage; the file ENDS with `COLLECTION COMPLETE — RUNID: <id>` and the
judge FAILS CLOSED (report ERROR, never score) if the file is absent,
RUNID mismatches, or the completeness sentinel is missing; dispatcher
cleans the file post-run.
DISPATCHER CONTRACT (confirmation MAJOR — fail-closed at the judge must
not fail OPEN at the pipeline): on a judge ERROR the orchestrator
(/seo /geo /harden /onboard) STOPS — no template dispatch, no L1 apply —
surfaces the ERROR verbatim, retries ONCE with a fresh collect+judge,
then escalates to the human. A mute or ERROR judge is NEVER carried into
templating (verify-secure-loop discipline). This handler is part of the
W5 skill rewrites, census-locked.
Explicit field list per LRN-126 (STEP 1-2 business+tech context consumed
by ALL later steps — full enumeration REQUIRED before cutting).
seo-data.test.sh locks (fetch.sh wiring) move with the worker body —
update suite same commit.
S4 geo-analyzer → geo-worker (sonnet, 2 modes) + geo-judge (opus) — mirror of
S3 incl. run-scoped `.audit/geo-signals-<RUNID>.md` + the same dispatcher
ERROR contract. No cross-domain file share:
seo vs geo bodies genuinely diverge (different checks, scoring blocks,
envelopes) — that divergence, not LRN-125, is the reason.
S5 handover-doc-writer → handover-synthesizer (opus; STEP 9 memory-registry
load + STEP 10 phase clustering + STEP 12 6-chapter synthesis — STEP 9
allocated here, it feeds the synthesis; correctness MINOR) +
handover-renderer (sonnet; STEP 13-16 annex render, precheck apply,
deterministic gates, HTML/PDF). client-handover-writer dispatches
synthesizer then renderer; PACKAGE contract split per LRN-126
(re-enumerate DEPLOY_HINTS/--skip-seo class fields — the EXACT prior
failure). W4 MUST same-commit relock model-routing.test.sh:52-55 (the
handover-doc-writer name + dispatch-string locks break on the rename;
"make test green per wave" D4 invariant — correctness MINOR).
Tier-downs (no split): validator-analyzer opus→sonnet (deterministic
validators+tables). onboarder stays sonnet wave 1 (haiku candidate wave 2).
release-executor stays sonnet (NEED-DECISION valve).
Verifier: STAYS sonnet (approved — oracle-anchored gate).
## D2 — SKILL MAP (main loop = session model; every dispatch tier explicit)
Gated reflection skills (model-gate kept, 15):
- ship-feature / init-project: per the two example maps in the analysis file
(amendment section) + S1 gate hoist at STEP 0 + doc-commit conversions.
- feat: scope/plan/contract/loop = main; challenge 3× plan-challenger opus;
feater sonnet; verifier+security sonnet; doc-commit → doc-auditor opus +
doc-syncer sonnet dispatch; commit via /commit-change (propose opus / apply
sonnet).
- bugfix: investigation/diagnosis/contract = main (reflection); challenge
opus (3b); bugfixer sonnet; verifier+security sonnet; doc-commit as feat.
- hotfix: LOCATE + guard = main (logic); challenge opus when guard fires;
hotfixer sonnet; security gate sonnet (revert-not-loop conserved);
doc-commit as feat.
- analyze: analyzer INLINE = main loop (it IS the reflection) — unchanged.
- code-clean: PHASE 1 audit inline = main (audit judgment feeding a human
gate); code-cleaner sonnet PHASE 2 (hosts refactorer inline at SAME tier —
LRN-125 OK); re-audit sonnet inside executor.
- seo / geo: skill = orchestration + GATED arbitrage (main); pipeline
collector sonnet → judge opus → templater sonnet (L1 serial); appliers
hotfixer/feater sonnet at L1; build-verify inline.
- web-validate: validator-analyzer sonnet; hotfixer applier sonnet; loop main.
- harden: audit dispatch follows S3 narrow-scope path (seo-judge opus on
harden axes w/ collector reuse); direct-Edit apply stays inline (tiny
scope, BDR-061 carve-out conserved).
- audit-delta: axis audits dispatched opus (delta judgment); security-auditor
sonnet; fix gate + markers = main.
- tour: orchestration main; security-auditor sonnet; cleanup audit = analyzer
opus (or general-purpose model="opus"); fixes via sonnet appliers; doc axis
→ S2 pipeline; reconcile axis = deterministic bash (main).
- onboard: onboarder DISPATCHED sonnet (was inline); plugin S1 pipeline;
analyzer opus; general-purpose audits model="opus" (kept); seo/geo → S3/S4
pipelines; security-auditor + doc pipeline as above; synthesis
general-purpose model="opus"; backlog arbitration = main.
- client-handover: writer INLINE (orchestrator, main); its 8 skill-runner
children model="fable"; handover S5 split (synth opus → render sonnet);
gates all main.
Excluded-from-gate skills (5, stay ungated): commit-change (propose opus /
apply sonnet via model=; approval gates main); doc (S2: auditor opus →
gate main → patcher sonnet); status (haiku); release-candidate (executor
sonnet; version/when/push decisions main); refactor (refactorer sonnet).
Memory/util skills (capitalize, close, prune-memory, reconcile, learn,
profile, skills-perso, gitflow, deploy, plugin-check(S1), status): main
loop by nature (conversation context, human gates, deterministic bash) —
no dispatch changes except plugin-check S1.
External/gstack skills (graphify, design-*, review, qa, ship, investigate…):
NOT edited (external ownership, BDR-015 class) — covered by doctrine line;
local wrapper skills only if locally owned. Verify ownership per file
before touching (symlink → skip).
## D3 — WAVES (each = gitflow feature branch, tests green, census extended)
W0 SEQUENCING: merge `feature/opus-pin-audit-agents` → develop (baseline,
human gate). `bugfix/seo-geo-integrity` is ALREADY MERGED (correctness
MAJOR — the TODO.md "UNMERGED" note was stale; verified `92301fe` is an
ancestor of develop AND this branch): no arbitrage, no W5 wait — one-line
ancestry re-check in W0 + fix the stale TODO.md entry (reconcile-class
correction). Absorb the analysis+plan files into the new feature branch.
W1 NO-INHERIT ENFORCEMENT (small, high-value): code-review model= opus
(ship-feature 6, init-project 10); client-handover-writer 8× model="fable";
doctrine line in model-gate.md + census locks (`model="fable"`,
`model=` presence per site); SDD sonnet prose → census lock. Prose sweep
of stale BDR-066/076 claims touched by W1.
W2 INLINE→DISPATCH CONVERSIONS: scaffolder (init 5 — liveness pings move to
orchestrator; scaffolder loses PHASE 6 inline-load → init 5b owns README
via S2), onboarder (onboard), doc-commit steps ×5 flows → S2 pipeline
(gate hoist FIRST: /doc + flows own the validation gate; doc-syncer body
loses its inline gate → census re-lock), S1 plugin split + gate hoist ×4
consumers. Data-flow pass per LRN-126 on each (fields enumerated in the
wave's contract file before edits).
W3 TIER MOVES: validator-analyzer → sonnet (pin + prose + census flip);
commit-changer per-mode model= (2 sites + prose + census).
W4 S5 handover split (synth opus / render sonnet) + PACKAGE re-enumeration.
W5 S3/S4 seo/geo pipelines: worker(2-mode)/judge ×2, /seo /geo /harden
/onboard rerouted, seo-data.test.sh moved locks, run-scoped signals
handoff (RUNID + completeness sentinel + fail-closed judge),
envelope/sentinel/score grammars verbatim, COVERAGE lines preserved.
W6 DOCTRINE + CLOSE-OUT: model-gate.md rewrite (protects main loop; tier
table; fable-dispatch doctrine), challenge-plan.md + plan-challenger
ORCHESTRATOR PROTOCOL text (keep BDR-066+BDR-076 tokens per census, add
BDR-077), census consolidation (model-routing new sections; every new
agent: YAML G3, pin lock, dispatch-string lock, AskUserQuestion/Agent
bans), LRN-113 whole-surface prose sweep (~30 refs list in analysis),
BDR-077 + LRN entries + journal, EVAL-023-style post-merge ronde.
Per-split planted-input smokes run IN their own waves (W2/W4/W5, merge
gates) — W6 is the consolidated ronde only, never the first empirical
proof of a split.
## D4 — ZERO-REGRESSION PROTOCOL (every wave)
- Before edits: wave contract file (.claude/tasks/contracts/) with FILE SCOPE
+ acceptance criteria; challenge-plan on THIS plan (done once, below);
verify-secure-loop on each wave's diff (verifier sonnet + security sonnet).
- Grammar diff-guard: `grep -F` each verbatim marker (analysis §CONSTRAINTS
list) pre/post per wave — zero drift.
- Census: flip-test every NEW lock (plant violation → RED) before trusting.
- `make test` green per wave; no wave merges without human signal (gitflow).
- Rollback story (robustness MINOR — waves are textually interdependent, an
early wave is NOT independently revertible after later merges): revert in
REVERSE merge order, or revert the whole stack; never a mid-stack single
revert. Pre-merge, the rollback unit is the wave branch.
## CHALLENGE LOG (2026-07-19 — 3 blind lenses on plan v1)
- correctness: CONCERNS(2) — seo-geo-integrity phantom sequencing (fixed W0);
commit-changer precedence ambiguity (fixed D1 + D0.2 citation + W3 smoke);
3 MINORs (S5 STEP 9 + W4 relock; plugin checkpoint seam; templater label)
— all fixed in place.
- robustness: FATAL(4) — BLOCKER fable-dispatch unverified → CLOSED by spike
(D0.2: resolves to claude-fable-5, enum-validated, loud failure); doc-commit
in-thread contract (fixed S2: CHANGE SUMMARY crosses the report grammar);
plugin-probe haiku contradiction (fixed: sonnet wave 1); signals handoff
freshness (fixed S3: RUNID + sentinel + fail-closed); rollback claim
(fixed D4).
- 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
fixed in v3: (a) per-split planted-input smokes moved IN-WAVE as merge
gates (W6 = ronde only); (b) dispatcher ERROR contract on judge failure
(STOP, no templating/apply, retry once, escalate — pipeline never fails
open); (c) transient signals files relocated to gitignored `.audit/`
(LRN-124). Protocol cap reached (1 re-challenge) → to the human gate.
+21
View File
@@ -6,6 +6,27 @@ Format follows [Keep a Changelog](https://keepachangelog.com/).
## [Unreleased]
## [1.2.0] — 2026-07-20
### Added
- **ctx7 coverage extension (BDR-078)** — the "consult current docs before coding against a fast-moving lib" doctrine now covers every code path, not just the two big pipelines. (1) `lib/fast-libs.sh`: single source of truth for fast-lib detection (`detect` / `cache-status` verbs; JS package.json anchored keys + Python requirements/pyproject; 7-day `.ctx7-cache/` freshness; locale-independent sort), replacing three hardcoded lists (`/ship-feature` STEP 0c, `/init-project` STEP 5c, `/onboard` STEP 3.5). (2) `hooks/ctx7-reminder.sh`: once-per-session UserPromptSubmit nudge when the project carries fast-libs and the cache is missing/stale — closes the ad-hoc-coding gap. (3) find-docs description extended with a before-writing-code trigger + a cache-first rule (read fresh cache, tee fetched docs back into it). (4) feater/bugfixer executor briefs gain the fast-lib docs rule (read fresh cache, else 2-topic `npx ctx7@latest` fetch, else report `ctx7 cache miss` and proceed). Second deliberate ctx7 surface — a scoped refinement of BDR-053's single-surface rule, not a reversal.
- **Adversarial plan-challenge phase** — reflection orchestrators now run a blind 3-lens challenge (correctness / robustness / simplicity) via a dedicated `plan-challenger` agent before implementation; severity-driven (a single-lens BLOCKER stops the plan), report-only. `/hotfix` joins behind a logic-only guard: cosmetic fixes skip it, logic fixes get challenged, a BLOCKER reroutes to `/bugfix` (BDR-075).
- **seo-data engine: measured coverage + new verbs** — the `/seo` FULL audit measures instead of feeling: `sitemap` verb gives COVERAGE a real denominator (source/live split); internal-link graph computes orphan pages + click depth; cannibalisation detected from GSC's own query data; `rich_results` surfaced from URL Inspection data already fetched; `sameAs` profiles actually resolved; `schema_gen` generates JSON-LD instead of only auditing it; `content_quality` runs a deterministic filler/AI-slop scan; the axis score is computed, not felt; `drift` baseline reports regressions vs changes. SPA pages: the audit refuses to score what JS paints instead of scoring the empty shell (no Playwright dependency). Common Crawl backlinks were measured (17 GB edges file) and killed as a source — the Off-page axis stays scoped to what is actually measured.
### Changed
- **Model-tiering v2: 4-tier explicit routing (BDR-076/077)** — the session model (Fable) does main-loop reflection/orchestration only; every dispatched subagent is explicitly tiered: judgment agents pinned opus (analyzer, plan-challenger, seo/geo audit agents…), mechanical executors sonnet, skill-runner children fable — nothing inherits silently. Mode-based splits so pins take effect: doc-syncer audit(opus)/patch(sonnet), handover-doc-writer synthesize(opus)/render(sonnet), seo/geo collect(sonnet)/judge(opus, fail-closed)/template(sonnet), plugin gate split probe(sonnet)/advisor(opus). Census locks (125) + per-wave planted-input smokes.
- **config-protection edit-block guardrail removed** (BDR-074) — the hook blocked more than it protected; deny-list design pass recorded in BDR-069.
- graphify vendored skill dist synced 0.9.6 → 0.9.15.
### Fixed
- **seo/geo integrity pass (I1–I8)** — Off-page axis scoped to measured data only; VSI (an SEO-blog fiction) removed from CWV thresholds; NAP direction rule ported into geo-analyzer (standalone `/geo` can no longer write unverified NAP); security headers no longer double-counted (`/harden` owns them); sampling coverage disclosed instead of implied; stats reattached to the claims they support; phantom audit precondition dropped. Plus two real bugs caught by a second-site backtest and two process anomalies from live dogfooding.
- `settings.json` Write() deny rules were inert — converted to Edit() rules, closing the write hole they left open.
- Model-routing W6 ronde: 6 findings closed (README bootstrap path, 2 census gaps, 3 stale refs).
### Security
- **`safe_fetch` resolve-then-pin** in `lib/seo-data` — DNS-rebinding closed on audit fetches: the audited host is resolved once, validated, then pinned for the actual fetch.
- **`url-guard`** — shell-injection + local-target refusal before any user-supplied or sitemap-crawled URL reaches curl (SSRF guard on the seo/geo fetch paths).
## [1.1.0] — 2026-07-16
### Added
+24 -15
View File
@@ -23,7 +23,7 @@ claude-config/
├── update-all.sh # One-command update for all components
├── Makefile # Unified entry point: make install / doctor / update
├── plugins.lock.json # Version pinning for non-marketplace dependencies
├── hooks/ # Session start, statusline, RTK rewrite + design-toolchain guards
├── hooks/ # Session start, statusline, RTK rewrite + ctx7 + design-toolchain reminders
├── agents/ # Execution units called by skills (never invoked directly)
├── skills/ # Entry points invoked via /skill-name
├── skills-external/ # Vendored skill packs (gstack submodule + installer-fetched design packs)
@@ -37,30 +37,35 @@ claude-config/
- `templates/` = symlinked to `~/.claude/templates/` — copy into projects via `/onboard` or manually
- **Graphify** builds a knowledge graph of any codebase (`/graphify query`), producing a navigable wiki in `graphify-out/wiki/`. This map helps Claude understand project structure, find relevant code faster, and reason across files. Essential for large-scope tasks (multi-file features, complex bugs, architectural changes). Small tasks should skip it and read files directly.
### Agent model routing (BDR-066)
### Agent model routing (BDR-076/077 — model-tiering v2)
Reflection (brainstorm, plan, contract, audit judgment, loop decisions) runs
INLINE on the session model — assumed Fable/Opus, enforced by a blocking
gate (`lib/model-gate.md` + `lib/model-check.sh`) at the entry of the 13
reflection orchestrators. Execution runs on pinned subagents:
Doctrine: the session model (Fable) does main-loop reflection ONLY —
brainstorm, plan, contract, audit judgment, gates, loop decisions — enforced
by a blocking gate (`lib/model-gate.md` + `lib/model-check.sh`) at the entry
of the 13 reflection orchestrators. Nothing dispatched inherits silently:
typed agents carry a frontmatter pin, built-ins get an explicit `model=` at
every call site.
| Agent | Model | Tier |
|---|---|---|
| feater, hotfixer, bugfixer | sonnet (pinned) | executors — code from a closed plan (feat), fix from a closed diagnosis (bugfix), fix-bundle appliers |
| verifier, security-auditor | sonnet (pinned) | fresh gates (≤3×/loop) |
| commit-changer, release-executor, code-cleaner | sonnet (pinned) | dispatched execution — grouping+commit / release spans / approved cleanup (the audit + approval gate stay in the dispatcher) |
| doc-syncer, onboarder, scaffolder, refactorer, interviewer, plugin-advisor | sonnet (pinned) | workers |
| commit-changer, release-executor, code-cleaner | sonnet (pinned) | dispatched execution — grouping+commit / release spans / approved cleanup (audit + approval gates stay in the dispatcher) |
| onboarder, scaffolder, refactorer, validator-analyzer, plugin-probe | sonnet (pinned) | workers — config generation, scaffold, refactor, deterministic W3C/WCAG runner, mechanical plugin probe |
| status-reporter | haiku (pinned) | mechanical collector |
| handover-doc-writer | sonnet (pinned) | deliverable writer — synthesizes + renders the client doc from a resolved PACKAGE (dispatched by client-handover) |
| analyzer, seo-analyzer, geo-analyzer, validator-analyzer, client-handover-writer | inherit session (Fable/Opus) | reflection / audit / inline playbooks / ship-and-handover pipeline |
| plan-challenger | inherit session (Fable/Opus) | fresh adversarial plan challenger — 3 parallel lenses (correctness/robustness/simplicity), dispatched by `/ship-feature` STEP 2b before the validation gate |
| analyzer, plan-challenger, plugin-advisor | opus (pinned) | dispatched judgment — pre-plan analysis, 3-lens adversarial plan challenge (`/ship-feature` STEP 2b), plugin-fit reasoning |
| seo-analyzer, geo-analyzer | opus pin (judge mode); collect/template spans dispatched `model="sonnet"` | 3-mode audit pipelines — judgment fail-closed on opus, mechanical collect + templating on sonnet |
| doc-syncer | sonnet pin; audit mode dispatched `model="opus"` | two-mode: audit (drift judgment, opus) / patch (mechanical apply, sonnet) |
| handover-doc-writer | sonnet pin; synthesize mode dispatched `model="opus"` | two-mode: synthesize (opus) / render (sonnet) — client deliverable |
| interviewer, client-handover-writer | unpinned (inline-load = session model) | they ARE the main loop — a frontmatter pin would be inert |
| Explore (built-in) | inherit session (Fable/Opus) | search feeds reflection — kept on the big model, not pinned down |
The pure-execution skills `/doc`, `/status`, `/commit-change`,
`/release-candidate` **dispatch** their agent (instead of inline-loading it)
so the pin takes effect and the work leaves the big session model; `/hotfix`
was split like `/feat` (reflection inline + gate, `hotfixer` executor) and so
joins the gated group (13th).
joins the gated group (13th); `/client-handover`'s nested skill-runner
children are dispatched `model:"fable"` (they carry reflection).
---
@@ -84,9 +89,12 @@ All scripts use their own location to find the repo — run them from anywhere.
The plugins step logs to `install-YYYYMMDD-HHMMSS.log`.
**Optional — Context7** (fast doc lookup for React / Next.js / Prisma…): the plugins
step installs the `ctx7` CLI and wires it into Claude Code itself — single surface =
the `find-docs` skill; the generated `rules/context7.md` is purged by design
(BDR-053). If you run `ctx7 setup` manually, delete that rule or re-run `make plugin`.
step installs the `ctx7` CLI and wires it into Claude Code. The doc-fetch surface is
the `find-docs` skill alone (BDR-053 — the generated `rules/context7.md` is purged by
design; if you run `ctx7 setup` manually, delete that rule or re-run `make plugin`).
A once-per-session `ctx7-reminder` hook nudges toward it when the current project
carries fast-moving libs (`lib/fast-libs.sh`) — a scoped second surface refining
BDR-053, not reversing it (BDR-078).
```bash
ctx7 login # optional: OAuth / API key for higher rate limits
@@ -186,6 +194,7 @@ cd my-existing-project/
/ship-feature "feature description"
# → STEP 0: plugin check
# → STEP 1-2: brainstorm + plan (superpowers)
# → STEP 2b: adversarial plan-challenge (3 lenses, report-only)
# → STEP 3: validation gate — user approval required
# → STEP 4-7: implement (TDD) → review → capitalize (memory)
# → STEP 8: sync README (doc-sync)
+1
View File
@@ -2,6 +2,7 @@
name: analyzer
description: Analyze code, codebase, or problem before any modification. Produces a factual report without proposing solutions. Use proactively before any refactoring, design, or implementation.
tools: Read, Grep, Glob, Bash
model: opus
memory: project
---
+6
View File
@@ -36,6 +36,12 @@ Every choice was made in the plan or is a NEED-DECISION to report.
before reporting.
- Follow existing code patterns and CLAUDE.md limits (function size, params,
no global state). Keep the fix minimal — no "while we're here" cleanups.
- Fast-moving libs (`bash ~/.claude/lib/fast-libs.sh detect .` — React,
Next.js, Prisma…): before touching their APIs, read a fresh
`.ctx7-cache/<lib>*.md` if present; else fetch targeted docs, max 2
topics (`npx ctx7@latest library <name> "<q>"` then `docs <id> "<q>"`).
ctx7 unavailable → add `ctx7 cache miss: <lib>` to NOTES and proceed on
model knowledge. Stable techs skip this entirely.
- FORBIDDEN: `git commit`, branch ops, push, merge, new dependencies,
security/verifier dispatch, editing `.claude/**` or memory registries, user
questions (you cannot ask — report instead), attribution trailers of any kind.
+44 -11
View File
@@ -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
---
@@ -257,7 +257,12 @@ pipeline is reduced: only run /cso (single audit, single fix loop), skip
STEP 6 deploy pause and STEP 7 /web-validate. Treat /cso as the only score for
the gate.
For web projects, dispatch in **a single message with two parallel Agent calls**:
**Model routing (BDR-077):** EVERY `general-purpose` skill-runner dispatch in
this pipeline (initial audits, fix-loop re-dispatches, commit-change,
web-validate) carries `model: "fable"` — the child hosts gated orchestration
on the pipeline's behalf; it must never inherit the session model.
For web projects, dispatch in **a single message with two parallel Agent calls** (each with `model: "fable"`):
| Audit (web) | Subagent | Prompt template |
|---------------|-------------------|-----------------|
@@ -383,7 +388,7 @@ console). If no projected line is parseable, treat projected = 17
### Re-dispatch prompt template (SEO + GEO loop)
Send to `general-purpose` subagent:
Send to `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/seo/SKILL.md` and re-run it on this project.
> Previous scores:
@@ -413,7 +418,7 @@ Send to `general-purpose` subagent:
### Re-dispatch prompt template (HARDEN loop)
Send to `general-purpose` subagent:
Send to `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/harden/SKILL.md` and re-run it. Previous score:
> **`<SCORE_HARDEN_PREVIOUS>`/20** — below threshold. Iteration `<N>` of
@@ -424,7 +429,7 @@ Send to `general-purpose` subagent:
### Re-dispatch prompt template (CSO loop — non-web only)
Send to `general-purpose` subagent:
Send to `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/cso/SKILL.md` and re-run it in **daily mode**.
> Previous score: **`<SCORE_CSO_PREVIOUS>`/20** — below threshold.
@@ -510,7 +515,7 @@ listed changes manually before deploy." Continue to STEP 6.
If `PENDING_CHANGES` non-empty → invoke /commit-change skill via subagent:
> Dispatch `general-purpose` subagent. Prompt:
> Dispatch `general-purpose` subagent (`model: "fable"`). Prompt:
>
> "Read `~/.claude/skills/commit-change/SKILL.md` and execute. All pending
> changes were produced by the client-handover ship pipeline during the
@@ -617,7 +622,7 @@ Skip if `VALIDATE_SKIPPED=true` or `PROJECT_TYPE != web` (in either case
ensure `VALIDATE_SKIPPED=true` is set so the gate logic in STEP 8 treats
VALIDATE as not-applicable rather than failed).
Dispatch `general-purpose` subagent:
Dispatch `general-purpose` subagent (`model: "fable"`):
> Read `~/.claude/skills/web-validate/SKILL.md` and execute against the
> deployed URL: `<DEPLOYED_URL>`. Audit W3C HTML validity (validator.nu),
@@ -1067,11 +1072,30 @@ If `OUTPUT` resolved to `skip-write`, still dispatch — the doc-writer
reports `MD: skipped` and stops before rendering, per its own
contract.
Dispatch:
Dispatch the two-mode pipeline (BDR-077 — synthesis on opus, render on the
sonnet pin, full PACKAGE both times per LRN-126). Mint a RUNID first
(`RUNID=$(date +%s)`); the draft crosses via the run-scoped, gitignored
`.audit/handover-draft-<RUNID>.md`; clean it after 9.7.
FIRST — synthesize:
```
Agent(subagent_type="handover-doc-writer", model="opus")
prompt: "MODE: synthesize
RUNID: <RUNID>
PACKAGE:
<the FULL PACKAGE block below>"
```
Parse its `SYNTH REPORT`: `STATUS: BLOCKED` → surface verbatim, stop (do
not patch the PACKAGE silently); malformed/mute → retry ONCE fresh, then
escalate. `STATUS: DONE` → THEN render:
```
Agent(subagent_type="handover-doc-writer")
prompt: "PACKAGE:
prompt: "MODE: render
RUNID: <RUNID>
PACKAGE:
LANG: <LANG>
PROJECT: name=<name> root=<root> type=<type> sub-type=<sub-type>
is_local_business=<bool> deployed_url=<url> period=<first→last>
@@ -1087,10 +1111,15 @@ PRECHECK_DONE: <list>
CLIENT_NAME: <name|—>
OUTPUT: <overwrite <path> | versioned <path> | skip-write>
Synthesize + write + render the deliverable per your steps. Report the
HANDOVER-DOC REPORT."
Render the deliverable from the draft per your render-mode steps. Report
the HANDOVER-DOC REPORT."
```
(The PACKAGE block is IDENTICAL in both dispatches — write it once,
paste it twice. A render `STATUS: BLOCKED` on draft absence/RUNID
mismatch means the synthesize leg failed silently: re-run 9.6 from the
synthesize dispatch, never hand-write the draft.)
### 9.7 — Parse the report, tell the user
Parse the returned `HANDOVER-DOC REPORT`:
@@ -1101,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).
+5
View File
@@ -7,6 +7,11 @@ model: sonnet
# Git Smart Commit
> MODEL (BDR-077): `MODE: propose` is dispatched with `model="opus"` (the
> call-site override — narrative reconstruction + capitalize routing are
> judgment); `MODE: apply` runs on the sonnet frontmatter pin (mechanical
> staging/committing of an approved plan).
Reconstruct the development narrative from a working directory. The goal
is to create a git history that reads like a story of how the work was
done — each commit is one development step, in chronological order.
+88 -59
View File
@@ -1,6 +1,6 @@
---
name: doc-syncer
description: Detect stale PUBLIC documentation by cross-referencing git history against the doc layout (README, CHANGELOG, docs/**…) — dispatched by /doc and orchestrators. Convention-aware (Diátaxis, Keep a Changelog); never touches .claude/. Audit, report, patch.
description: 'Two-mode public-doc sync agent — MODE: audit (dispatched model="opus" — drift detection, semantic analysis, drafts, PATCH PLAN, read-only) and MODE: patch (sonnet pin — applies the APPROVED plan, oracle-checked, emits CHANGE SUMMARY + PATCHED_FILES). The validation gate lives in the DISPATCHER (BDR-077). Convention-aware (Diátaxis, Keep a Changelog); never touches .claude/.'
tools: Read, Write, Edit, Bash, Grep, Glob
model: sonnet
---
@@ -54,18 +54,25 @@ audit, report, and patch.
---
## MODE DETECTION
## MODE DETECTION (BDR-077 — two dispatch modes around the dispatcher's gate)
Parse `$ARGUMENTS`:
- **AUTO MODE** — `$ARGUMENTS` starts with `auto-mode scope:`
Jump to AUTO MODE section.
- **FULL AUDIT** — anything else (empty, file list, description).
Run the full audit workflow.
- **CLEAN MODE** — set when `$ARGUMENTS` contains the token `clean`.
Modifier on FULL AUDIT: run the full audit AND propose removal of
out-of-convention content already present in public docs (see
STEP 6.5). Not a separate flow.
- **`MODE: patch`** — the dispatcher approved a PATCH PLAN and re-dispatches
this agent to APPLY it. Jump to MODE: PATCH section. Runs on the sonnet
frontmatter pin.
- **`MODE: audit`** (or no explicit MODE — audit is the default) — analysis
half, dispatched with `model: "opus"` (judgment tier; the call-site
override takes precedence over the sonnet pin). **READ-ONLY: Write and
Edit are FORBIDDEN in audit mode** — CREATE items are rendered as DRAFTS
inside the report, never written. Sub-variants:
- `auto-mode scope:` prefix → AUTO MODE section (scoped quick audit).
- `clean` token → CLEAN modifier on the full audit (STEP 6.5).
- anything else → FULL AUDIT workflow.
- **The validation gate is NOT yours.** A dispatched agent cannot ask the
user. You emit the report + PATCH PLAN (audit) or apply the approved plan
(patch); the DISPATCHER runs the gate between the two (see DISPATCHER
PROTOCOL).
---
@@ -373,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
@@ -662,19 +670,36 @@ 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,
nothing out-of-convention): `DOC SYNC: all docs current` and stop.
### STEP 8 — VALIDATION GATE (mandatory stop)
**PATCH PLAN (machine block — closes every audit report that found drift).**
The dispatcher's gate approves items BY ID; the approved subset is what a
`MODE: patch` re-dispatch receives, verbatim:
```
PATCH PLAN
P1. [AUTO] <file> — <section> — <exact change, diffable>
P2. [HUMAN] <file> — <section> — <exact change> — reason: <…>
C1. [CREATE-AUTO] README.md — write the rendered draft above
C2. [CREATE-HUMAN] DEPLOY.md — write the rendered draft above
R1. [REMOVE] <file> — <block to excise> (CLEAN items likewise)
```
### DISPATCHER PROTOCOL — VALIDATION GATE (consumer contract — the gate
### runs in the DISPATCHER'S MAIN LOOP, never in this dispatched agent)
The dispatcher presents:
```
DOC SYNC — VALIDATION GATE
AUTO items : <count> (Claude will patch these)
AUTO items : <count> (will be patched)
HUMAN items : <count> (listed above for review)
CREATE items : <count>
- README.md (AUTO — will be written; `edit` to refine the rendered draft)
@@ -694,22 +719,40 @@ README.md CREATE is unconditional: the only valid responses are `yes`
write). Treat any `no` / `skip` answer to README as `edit` and prompt
the user for the specific changes they want.
Wait for explicit approval. Do not proceed without it.
The dispatcher waits for explicit approval, then re-dispatches this agent
with `MODE: patch` + the APPROVED PATCH PLAN (approved item lines verbatim,
including the rendered drafts for approved CREATE items). Nothing is
applied without that round-trip.
### STEP 9 — PATCH
## MODE: PATCH
Apply only approved items. **Never write under `.claude/` or to
`CLAUDE.md`** — they are not targets under any circumstance.
INPUT: `MODE: patch` + the APPROVED PATCH PLAN (item lines verbatim — the
dispatcher's gate already decided; you re-decide NOTHING, you re-analyse
NOTHING). Plan absent or empty → report `DOC PATCH: empty plan — nothing
applied` and stop.
Apply only the listed items. **Never write under `.claude/` or to
`CLAUDE.md`** — they are not targets under any circumstance; a plan line
targeting them is refused loudly (report it, apply nothing else from it).
- Surgical Edit for AUTO items. Preserve structure and tone.
- Write for approved CREATE items (README, DEPLOY). Use real project
data only — no `<TODO>` placeholders, no fabricated feature
descriptions.
- Write for approved CREATE items (README, DEPLOY) using the approved
rendered draft. Real project data only — no `<TODO>` placeholders, no
fabricated feature descriptions.
- For removals (REMOVE / INLINE / CLEAN), prefer Edit (delete the
offending lines) over Write.
- Re-read each modified file post-edit to verify no broken markdown,
no orphaned references.
- **Shape oracle (auto-mode MINOR provenance)**: when the plan carries
`[MINOR]`-provenance items (auto-mode flows), run
`bash "$HOME/.claude/lib/doc-shape.sh" check <every patched path>` (all
paths, ONE call) AFTER patching. exit 0 → keep. exit 1 (or 2/3 —
broken check never passes) → the oracle OVERRULES the MINOR call
(LRN-046): revert ALL this run's patches (`git checkout -- <each
patched path>`), and report `SHAPE ESCALATION: <oracle stderr>` —
the dispatcher re-gates as SIGNIFICANT. Never keep an out-of-shape
auto-patch.
### OUTPUT
### OUTPUT (MODE: patch)
```
DOC SYNC COMPLETE
@@ -719,6 +762,9 @@ CREATED : <count> files
REMOVED : <count> files / sections
HUMAN PENDING: <count> items (see report above)
SKIPPED : <count> (user declined)
CHANGE SUMMARY: (one line per patched file — what changed and why; the
doc-commit step's rc-0 visible surface consumes THIS, LRN-126)
<path> — <one line: what changed>
PATCHED_FILES: (one real path per LINE below; "(none)" if no write)
<path created or modified this run>
<path created or modified this run>
@@ -788,46 +834,29 @@ Categorize:
artifact (Dockerfile, fly.toml, workflow) without DEPLOY.md update or
creation.
### STEP A4 — ACT
### STEP A4 — REPORT (audit mode is read-only; the ACTING is the dispatcher's)
- **NONE** → exit completely silent. No output (no `PATCHED_FILES` → the doc-commit step
sees an empty list and no-ops).
- **MINOR** → patch, then VERIFY SHAPE with the deterministic oracle BEFORE the
silent auto-commit. The LLM made the MINOR call; the oracle re-checks that the
patch's SHAPE actually holds, catching a SIGNIFICANT mislabeled MINOR (RISK-1):
```
bash "$HOME/.claude/lib/doc-shape.sh" check <every patched path> # all paths, ONE call
```
- **exit 0** (within the MINOR envelope) → genuine MINOR: keep the silent patch.
One-line confirmation per file: `doc-sync: patched <file> (<what changed>)`.
Proceed to `PATCHED_FILES` + the doc-commit step.
- **exit 1** (shape EXCEEDS — oracle stderr names the offender(s) and why) → the
deterministic oracle OVERRULES the LLM's MINOR call (LRN-046). Do NOT auto-commit.
ESCALATE the WHOLE patch set to the SIGNIFICANT gate below — one file out of
shape makes the atomic MINOR classification suspect. Surface every patched file
+ the oracle's reason, then the gate: on `no` → revert ALL
(`git checkout -- <each patched path>`); on `select` → keep the chosen files,
revert the rest. The oracle catches STRUCTURAL/size significance, not semantic —
it is a deterministic floor, not a full SIGNIFICANT-detector.
- **exit 2/3** (oracle usage error / not a git repo) → do NOT auto-commit on a
broken check; treat as exit 1 and escalate.
- **SIGNIFICANT** (or a MINOR the oracle escalated) → surface to user before patching:
- **NONE** → exit completely silent. No report, no PATCH PLAN (the
dispatcher sees nothing to do; the doc-commit step no-ops).
- **MINOR** → emit a minimal report + `PATCH PLAN` whose items carry the
`[MINOR]` provenance tag. The DISPATCHER re-dispatches `MODE: patch`
DIRECTLY, no gate (preserved auto behavior — MINOR is auto-committed;
the deterministic shape oracle runs in patch mode and a
`SHAPE ESCALATION` comes back to the dispatcher, which then gates the
set as SIGNIFICANT: on `no` the reverts already happened; on `select`
it re-dispatches patch with the kept subset).
- **SIGNIFICANT** (or a MINOR the oracle escalated back) → emit the report
+ PATCH PLAN; the DISPATCHER gates:
```
DOC SYNC — drift detected after this session:
<list of significant items with proposed fixes>
Apply? (yes / no / select)
```
Wait for approval.
then re-dispatches `MODE: patch` with the approved subset.
After writing in MINOR or approved-SIGNIFICANT, emit the machine-readable handle the
doc-commit step (`lib/doc-commit.md`) consumes — ONE real path PER LINE:
```
PATCHED_FILES:
<path created or modified this run>
<path created or modified this run>
```
Emit ONLY when something was written; NONE stays silent. Never lists `.claude/**` or
`CLAUDE.md` (never targets, BDR-022).
`PATCHED_FILES` + `CHANGE SUMMARY` are emitted by `MODE: patch` only (see
its OUTPUT) — audit mode writes nothing, so it never emits them. Neither
ever lists `.claude/**` or `CLAUDE.md` (never targets, BDR-022).
---
+6
View File
@@ -47,6 +47,12 @@ report below is optional on this path (the dispatcher needs the edit applied
suite incrementally; run it fully before reporting.
- Follow existing code patterns and CLAUDE.md limits (function size,
params, no global state). Match comment density and naming.
- Fast-moving libs (`bash ~/.claude/lib/fast-libs.sh detect .` — React,
Next.js, Prisma…): before coding against their APIs, read a fresh
`.ctx7-cache/<lib>*.md` if present; else fetch targeted docs, max 2
topics (`npx ctx7@latest library <name> "<q>"` then `docs <id> "<q>"`).
ctx7 unavailable → add `ctx7 cache miss: <lib>` to NOTES and proceed on
model knowledge. Stable techs (C, SQL, POSIX sh…) skip this entirely.
- FORBIDDEN: `git commit`, branch ops, push, merge, new dependencies,
editing `.claude/**` or memory registries, user questions (you cannot
ask — report instead), attribution trailers of any kind.
+34
View File
@@ -2,6 +2,7 @@
name: geo-analyzer
description: GEO audit agent for AI search engines — dispatched by /geo and /seo. Audits AI crawlers, llms.txt, entity signals, Schema.org; emits a fix bundle (dispatcher applies), scored report. Classical SEO → seo-analyzer agent.
tools: Read, Edit, Write, Bash, Grep, Glob, WebFetch, WebSearch
model: opus
---
# GEO — Generative Engine Optimization audit, fix & strategy
@@ -93,6 +94,31 @@ $ARGUMENTS
---
## MODE DETECTION (BDR-077 — pipeline modes around the dispatcher)
Mirror of seo-analyzer's pipeline contract. Parse the MODE line:
- **`MODE: collect`** — dispatched `model: "sonnet"`. STEP 0-5 ONLY
(context, crawler policy probes, llms.txt checks — raw results), written
to the run-scoped, gitignored `.audit/geo-signals-<RUNID>.md`, terminated
by `COLLECTION COMPLETE — RUNID: <RUNID>`; emit a `COLLECT REPORT`
(`STATUS`, RUNID, COVERAGE counts) and STOP.
- **`MODE: judge`** — opus frontmatter pin. Fail-closed load of
`.audit/geo-signals-<RUNID>.md` (absent / RUNID mismatch / missing
sentinel → `GEO JUDGE — VERDICT: ERROR(<reason>)`, STOP — never score
stale or partial signals). Then STEP 6-12 (schema, entity — including
its verification curls — content shape, visibility, scoring, plan,
triage) reported as findings + scores + batches. No bundle, no GEO.md.
- **`MODE: template`** — dispatched `model: "sonnet"`. INPUT: dispatcher
context + judge report VERBATIM (never re-derive). STEP 13-15: FIX
BUNDLE + sentinel, report file, envelope, console.
- **No MODE line** — legacy single-shot on the opus pin (/onboard
report-only).
Every mode receives the full dispatcher CONTEXT block (LRN-126).
---
## STEP 0 — AUDIT DEPTH
**First action.** If not already determined by a parent skill (`/seo`
@@ -323,6 +349,10 @@ RECOMMENDATION : CREATE | UPDATE | OK | SKIP (low value for this site type)
---
> **MODE BOUNDARY — `MODE: collect` ends at STEP 5**: signals file +
> `COLLECTION COMPLETE — RUNID: <RUNID>` written, COLLECT REPORT emitted,
> stop. STEP 6-12 below are `MODE: judge` territory.
## STEP 6 — SCHEMA.ORG FOR AI `[both]`
Load: `~/.claude/agents/resources/geo-schemas.md`
@@ -803,6 +833,10 @@ one level up, where the plan is printed and the user can interrupt.
---
> **MODE BOUNDARY — `MODE: judge` ends at STEP 12** (findings + scores +
> batches reported). STEP 13-15 below are `MODE: template` territory,
> operating on the judge report verbatim.
## STEP 13 — EMIT FIX BUNDLE `[both]`
**You do NOT apply fixes and you do NOT dispatch any sub-agent.** Same
+30 -1
View File
@@ -1,6 +1,6 @@
---
name: handover-doc-writer
description: Deliverable writer — dispatched by client-handover with a resolved PACKAGE. Reads memory + git, synthesizes the 6-chapter client doc, writes the MD, renders branded HTML+PDF. No audits, no questions, no dispatch.
description: 'Two-mode deliverable writer — MODE: synthesize (dispatched model="opus" — memory+git clustering, 6-chapter synthesis into a run-scoped draft) and MODE: render (sonnet pin — annexes, precheck, deterministic gates, MD + branded HTML/PDF from the draft). Dispatched twice by client-handover with the resolved PACKAGE. No audits, no questions, no dispatch.'
tools: Read, Write, Edit, Bash, Grep, Glob, WebSearch, WebFetch
model: sonnet
---
@@ -43,6 +43,29 @@ name the missing field.
---
## MODE DETECTION (BDR-077 — two dispatch modes, one PACKAGE)
The parent dispatches this agent TWICE, with the FULL PACKAGE both times
(LRN-126 — every field crosses each dispatch) plus a `RUNID`:
- **`MODE: synthesize`** — dispatched with `model: "opus"` (judgment tier;
call-site override over the sonnet pin). Runs STEP 9 → 10 → 12 and writes
the chapters (§1-§6 full, §7/§8 stubs) into the RUN-SCOPED DRAFT
`.audit/handover-draft-<RUNID>.md`, ending the file with the line
`DRAFT COMPLETE — RUNID: <RUNID>`. Then emits a `SYNTH REPORT`
(`STATUS: DONE | BLOCKED`, RUNID, phase-cluster count, per-chapter word
counts) and STOPS — STEP 13-16, the final MD, HTML and PDF are NEVER
this mode's job.
- **`MODE: render`** — runs on the sonnet frontmatter pin. FIRST loads the
draft: absent file, RUNID mismatch, or missing `DRAFT COMPLETE` sentinel
→ `STATUS: BLOCKED` naming the cause (fail closed — never synthesize a
missing draft, never render a partial one). Then runs STEP 13 → 14 →
14.5 → 15 → 16 on the draft + PACKAGE and emits the `HANDOVER-DOC
REPORT`. `OUTPUT = skip-write` → report `MD: skipped` and stop before
rendering, as before.
---
## STEP 9 — LOAD MEMORY REGISTRIES
```bash
@@ -452,6 +475,12 @@ des audits de santé. Pour toute question, contactez [contact].*
---
> **MODE BOUNDARY.** STEP 12 is the last synthesize-mode step: write the
> drafted chapters to `.audit/handover-draft-<RUNID>.md` (+ the
> `DRAFT COMPLETE — RUNID: <RUNID>` terminal line), emit the SYNTH
> REPORT, stop. Everything below (STEP 13-16) is `MODE: render` and
> operates ON that draft.
## STEP 13 — SEO/GEO MANUAL CHECKLIST (web projects only)
If `PROJECT_TYPE=web` AND `PACKAGE.SKIP_SEO` is not `yes`, append this chapter
+5 -2
View File
@@ -2,6 +2,7 @@
name: plan-challenger
description: Fresh independent plan challenger — reads a PLAN file from disk and adversarially attacks it through ONE assigned lens (correctness | robustness | simplicity), then renders structured findings + a verdict. Report-only, never fixes, never implements. Dispatched fresh; blind to the other lenses.
tools: Read, Grep, Glob, Bash
model: opus
---
# PLAN-CHALLENGER AGENT
@@ -93,8 +94,10 @@ the MAIN loop, never here):
- Dispatch THREE fresh challengers IN PARALLEL, one per lens
(correctness / robustness / simplicity), each blind to the others.
- MODEL (BDR-066): plan critique is AUDIT JUDGMENT, not a procedural gate — do
NOT pin `model: "sonnet"`; the challenger inherits the big session model.
- MODEL (BDR-076, supersedes the BDR-066 inherit): plan critique is AUDIT
JUDGMENT, not a procedural gate — the challenger is `model: opus`-pinned in
its frontmatter (big tier, session-independent; the session model stays on
the inline loop). Never `model: "sonnet"` — a silent judgment downgrade.
(Contrast the verifier, Sonnet-pinned only because it is oracle-anchored to a
contract.)
- FAIL-SAFE — never fail open: a malformed/empty verdict, a missing `PROOF`, or
+27 -120
View File
@@ -1,71 +1,35 @@
---
name: plugin-advisor
description: Plugin-fit checker — dispatched by /plugin-check and orchestrator gates (init-project, ship-feature). Recommends enable/disable.
tools: Read, Bash, Glob, Grep
model: sonnet
description: Plugin-fit REASONER — dispatched by lib/plugin-gate.md with a PROBE REPORT (from plugin-probe). Classifies signals, scores complexity, recommends enable/disable via the decision table + compatibility matrix. Report-only.
tools: Read, Glob, Grep
model: opus
---
# PLUGIN ADVISOR
## ROLE
Detect active plugins and project signals. Recommend enable/disable. Apply compatibility matrix. Block or warn as needed.
Reason over the PROBE REPORT + request. Classify signals, score complexity,
recommend enable/disable, apply the compatibility matrix. Block or warn.
Detection is NOT your job (plugin-probe did it); applying is NOT your job
(the dispatcher's lib/plugin-gate.md apply gate does it).
---
## PHASE 1 — DETECT
## INPUT — PROBE REPORT (ground truth, from plugin-probe)
```bash
# Claude Code plugins
claude plugin list 2>/dev/null || echo "plugin-list-unavailable"
# External (non-marketplace) tools status — gstack, emil-design-eng,
# darwin-skill. Managed by lib/toggle-external.sh since
# `claude plugin enable|disable` does not apply to them.
bash "$HOME/.claude/lib/toggle-external.sh" list 2>/dev/null || echo "toggle-external-unavailable"
# Active skill profile — design / dev / qa / audit / minimal / custom.
# Profiles partition gstack + personal skills by purpose. See
# lib/profile.sh and lib/profiles/*.profile.
bash "$HOME/.claude/lib/profile.sh" current 2>/dev/null || echo "profile-unavailable"
# Context7 CLI
command -v ctx7 &>/dev/null && ctx7 --version 2>/dev/null | head -1 || echo "ctx7-not-installed"
# Standalone CLIs
command -v gsd &>/dev/null && gsd --version 2>/dev/null | head -1 || echo "gsd-not-installed"
command -v rtk &>/dev/null && rtk --version 2>/dev/null | head -1 || echo "rtk-not-installed"
# Project signals (run from project root)
ls package.json pyproject.toml Cargo.toml go.mod 2>/dev/null | head -5
grep -rl "next\|react\|vue\|prisma\|supabase" package.json 2>/dev/null | head -3 || true
find . -name "*.tsx" -o -name "*.jsx" 2>/dev/null | head -3 | wc -l
find . -name "docker-compose*" -o -name "Dockerfile" 2>/dev/null | head -3 | wc -l
# Animation lib status (motion / motion-v) — read-only detection
if [ -f "$HOME/.claude/lib/animation-lib-check.sh" ]; then
source "$HOME/.claude/lib/animation-lib-check.sh"
detect_anim_eligibility # outputs '<status>|<package>|<reason>'
is_anim_lib_installed || echo "anim-lib-not-installed"
fi
# Monorepo detection (current dir + parent dirs for sub-package context)
ls apps/ packages/ services/ workspaces/ 2>/dev/null | head -5
ls pnpm-workspace.yaml turbo.json nx.json lerna.json 2>/dev/null
# Upstream check: detect if current dir is itself a package inside a monorepo
ls ../pnpm-workspace.yaml ../turbo.json ../nx.json ../../turbo.json ../../pnpm-workspace.yaml 2>/dev/null | head -3
# Embedded/firmware detection via filesystem
ls CMakeLists.txt platformio.ini 2>/dev/null
ls *.ld *.lds linker*.ld 2>/dev/null | head -3 # linker scripts = bare-metal
ls Makefile 2>/dev/null
# Presence of .c files used only when combined with Makefile AND no Node/Rust/Go manifest
ls src/*.c 2>/dev/null | head -3
ls package.json Cargo.toml go.mod pubspec.yaml setup.py pyproject.toml 2>/dev/null | head -1 # counterindicators (ecosystem present = not bare embedded)
```
The dispatcher passes `REQUEST` (the project description, verbatim) and the
full `PROBE REPORT` (fields: PLUGINS, EXTERNAL, PROFILE, CLIS, MANIFESTS,
FRAMEWORK-DEPS, TSX-JSX-COUNT, DOCKER-COUNT, ANIM, MONOREPO, EMBEDDED,
CHECKPOINT). Treat it as ground truth — never re-detect, never invent a
field. PROBE REPORT missing or a field absent → emit
`PLUGIN CHECK — VERDICT: ERROR(probe report missing/invalid: <what>)` and
STOP. Fail closed: no recommendations over invented detection.
---
## PHASE 2 — ANALYZE $ARGUMENTS
## PHASE 2 — ANALYZE
Detect signals from the project description and filesystem scan:
Detect signals from REQUEST + the PROBE REPORT fields:
| Signal | How to detect |
|---|---|
@@ -82,8 +46,8 @@ Detect signals from the project description and filesystem scan:
| `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) |
---
@@ -146,70 +110,11 @@ ACTION REQUIRED? YES / NO
> packages itself — it just states the status. Installation happens in
> `/init-project` STEP 5e (auto) or `/onboard` STEP 2.5 (opt-in).
## PHASE 4 — AUTO-ACTIVATION (when called from /init-project or /ship-feature)
After presenting RECOMMENDATIONS, if any plugin has ⚡ ENABLE status:
1. List the changes to apply:
```
PROPOSED CHANGES:
⚡ Enable ui-ux-pro-max (frontend detected, complexity 65%)
⚡ Pre-fetch ctx7 docs for next.js, prisma
Apply these changes? (yes / no / customize)
```
2. On "yes" → apply changes (rename .disabled dirs, update MCP config).
3. On "customize" → user picks which to apply.
4. On "no" → proceed with current config.
**Never auto-activate without showing the list and getting confirmation.**
### Rollback on partial failure
Toggle commands occasionally fail mid-batch (rename collision, permission, MCP
restart hang). Track each toggle and roll back the partial set rather than
leave a half-applied configuration:
```bash
applied=()
for change in "${PROPOSED_CHANGES[@]}"; do
if bash "$HOME/.claude/lib/toggle-external.sh" enable "$change"; then
applied+=("$change")
else
echo "❌ failed to enable $change — rolling back ${#applied[@]} prior change(s)"
for prior in "${applied[@]}"; do
bash "$HOME/.claude/lib/toggle-external.sh" disable "$prior" \
|| echo "⚠️ rollback of $prior also failed — manual cleanup required: see ~/.claude/plugins/cache"
done
exit 1
fi
done
```
Surface to the user:
```
✅ Applied N change(s).
```
Or, on failure:
```
⚠️ Toggle failed at change <name>. Rolled back the N prior change(s).
To inspect manually: ls ~/.claude/plugins/cache; bash ~/.claude/lib/toggle-external.sh list
Re-run /plugin-check after fixing the underlying cause (e.g. permissions).
```
### Pre-recommendation validation checkpoint
Between PHASE 1 (DETECT) and PHASE 2 (ANALYZE), validate the detection
findings before producing recommendations:
- `toggle-external.sh list` returned non-empty AND each listed plugin's
directory exists in `~/.claude/plugins/cache` or `~/.agents/skills/`.
- At least one project signal was detected (else: print `"⚠️ No project
signals detected — recommendations will be conservative."` and continue).
- If `toggle-external.sh` is missing or unexecutable: print `"⚠️ toggle script
unavailable — recommendations will be advisory only, no auto-activation."`
and skip PHASE 4 entirely.
> **Apply, confirmation, and rollback are the DISPATCHER'S job** —
> `lib/plugin-gate.md` steps 4-5 (main loop: present, ACTION-REQUIRED stop,
> PROPOSED-CHANGES confirmation, toggle + rollback). This agent only
> recommends and emits the EXACT toggle commands. It never applies, never
> asks the user (it cannot — it is dispatched).
---
@@ -418,4 +323,6 @@ or by applying a profile that lists it (e.g. `apply web` to restore
→ Free higher rate limits: `ctx7 login` (OAuth) or API key from context7.com/dashboard
→ Type "force" to proceed without context7 (not recommended for fast-evolving libs)
Never modify files. If action required → stop and wait. If not → say "proceed".
Never modify files. Never ask the user. Report-only: the PLUGIN CHECK block
is your entire output; the dispatcher's gate (lib/plugin-gate.md) owns the
stop/proceed decision and every state change.
+90
View File
@@ -0,0 +1,90 @@
---
name: plugin-probe
description: Mechanical detection probe — dispatched by lib/plugin-gate.md BEFORE the plugin-advisor reasoner. Runs the CLI/filesystem probes, reports raw facts as a PROBE REPORT. No analysis, no recommendations.
tools: Bash, Read, Glob, Grep
model: sonnet
---
# PLUGIN PROBE
## ROLE
Collect the raw plugin/project facts the plugin-advisor reasons over.
Facts only — no signals, no recommendations, no complexity scoring.
## PROBES (run all; a failing probe reports its fallback string, never aborts)
```bash
# Claude Code plugins
claude plugin list 2>/dev/null || echo "plugin-list-unavailable"
# External (non-marketplace) tools status — gstack, emil-design-eng,
# darwin-skill. Managed by lib/toggle-external.sh since
# `claude plugin enable|disable` does not apply to them.
bash "$HOME/.claude/lib/toggle-external.sh" list 2>/dev/null || echo "toggle-external-unavailable"
# Active skill profile — design / dev / qa / audit / minimal / custom.
bash "$HOME/.claude/lib/profile.sh" current 2>/dev/null || echo "profile-unavailable"
# Context7 CLI
command -v ctx7 &>/dev/null && ctx7 --version 2>/dev/null | head -1 || echo "ctx7-not-installed"
# Standalone CLIs
command -v gsd &>/dev/null && gsd --version 2>/dev/null | head -1 || echo "gsd-not-installed"
command -v rtk &>/dev/null && rtk --version 2>/dev/null | head -1 || echo "rtk-not-installed"
# Project signals (run from project root)
ls package.json pyproject.toml Cargo.toml go.mod 2>/dev/null | head -5
grep -rl "next\|react\|vue\|prisma\|supabase" package.json 2>/dev/null | head -3 || true
find . -name "*.tsx" -o -name "*.jsx" 2>/dev/null | head -3 | wc -l
find . -name "docker-compose*" -o -name "Dockerfile" 2>/dev/null | head -3 | wc -l
# Animation lib status (motion / motion-v) — read-only detection
if [ -f "$HOME/.claude/lib/animation-lib-check.sh" ]; then
source "$HOME/.claude/lib/animation-lib-check.sh"
detect_anim_eligibility # outputs '<status>|<package>|<reason>'
is_anim_lib_installed || echo "anim-lib-not-installed"
fi
# Monorepo detection (current dir + parent dirs for sub-package context)
ls apps/ packages/ services/ workspaces/ 2>/dev/null | head -5
ls pnpm-workspace.yaml turbo.json nx.json lerna.json 2>/dev/null
# Upstream check: detect if current dir is itself a package inside a monorepo
ls ../pnpm-workspace.yaml ../turbo.json ../nx.json ../../turbo.json ../../pnpm-workspace.yaml 2>/dev/null | head -3
# Embedded/firmware detection via filesystem
ls CMakeLists.txt platformio.ini 2>/dev/null
ls *.ld *.lds linker*.ld 2>/dev/null | head -3 # linker scripts = bare-metal
ls Makefile 2>/dev/null
# Presence of .c files used only when combined with Makefile AND no Node/Rust/Go manifest
ls src/*.c 2>/dev/null | head -3
ls package.json Cargo.toml go.mod pubspec.yaml setup.py pyproject.toml 2>/dev/null | head -1 # counterindicators (ecosystem present = not bare embedded)
# Checkpoint inputs (consumed by lib/plugin-gate.md's validation checkpoint)
[ -x "$HOME/.claude/lib/toggle-external.sh" ] && echo "toggle-script: executable" || echo "toggle-script: UNAVAILABLE"
ls "$HOME/.claude/plugins/cache" 2>/dev/null | head -10
ls "$HOME/.agents/skills" 2>/dev/null | head -10
```
## OUTPUT — PROBE REPORT (every field present; unavailable = the probe's fallback string, never invented)
```
PROBE REPORT
PLUGINS : <claude plugin list output, one per line>
EXTERNAL : <toggle-external list output>
PROFILE : <profile current output>
CLIS : ctx7=<v|absent> gsd=<v|absent> rtk=<v|absent>
MANIFESTS : <files found>
FRAMEWORK-DEPS: <grep hits in package.json>
TSX-JSX-COUNT : <n>
DOCKER-COUNT : <n>
ANIM : eligibility=<status|package|reason> installed=<lib|no>
MONOREPO : dirs=<hits> configs=<hits> parent=<hits>
EMBEDDED : cmake-pio=<hits> linker=<hits> makefile=<y/n> src-c=<hits> ecosystem=<first manifest|none>
CHECKPOINT : toggle-script=<executable|UNAVAILABLE> plugin-dirs=<cache+skills listing>
```
## RULES
- Facts only. No signal classification, no complexity score, no
recommendations — that is the plugin-advisor's job.
- Never modify files. Never install anything. Never ask the user
(you cannot — report facts instead).
- A probe that errors reports its fallback string; the report is emitted
with EVERY field line present regardless.
+5 -11
View File
@@ -123,16 +123,10 @@ INSTALL : ✅ / ❌ <error>
BUILD : ✅ / ❌ <error>
DOCKER BUILD: ✅ / ⚠️ not verified / N/A
STRUCTURE: <tree>
READY: <N> v1 features | entry points ✅ | config ✅ | CLAUDE.md ✅ | README → doc-syncer | settings ✅
READY: <N> v1 features | entry points ✅ | config ✅ | CLAUDE.md ✅ | README → init-project STEP 5b | settings ✅
```
---
## PHASE 6 — DOC SYNC (automatic)
**INLINE-LOAD** `$HOME/.claude/agents/doc-syncer.md` — continue AS
doc-syncer in THIS SAME context (you *become* it). This is an inline load,
NOT a subagent dispatch: the `Agent` tool is not involved (which is why
this agent correctly omits `Agent` from its `tools:`). Execute in
automatic mode:
`auto-mode scope: <list of all files created during scaffolding>`
> No doc step here (BDR-077): the scaffolder produces NO docs. The README
> bootstrap is init-project STEP 5b's job — a doc-syncer `MODE: audit`
> (opus) → `MODE: patch` (sonnet) dispatch pipeline owned by the
> orchestrator, never an inline-load inside this executor.
+41
View File
@@ -2,6 +2,7 @@
name: seo-analyzer
description: 'Classical SEO audit agent (Google, Bing) — dispatched from /seo. Live audit: Core Web Vitals, on-page, technical, local SEO, legal (FR). Emits a fix bundle (dispatcher applies) + scored report. AI/GEO → geo-analyzer agent.'
tools: Read, Edit, Write, Bash, Grep, Glob, WebFetch, WebSearch
model: opus
---
# SEO — Classical Search Engines audit, fix & strategy
@@ -23,6 +24,38 @@ $ARGUMENTS
---
## MODE DETECTION (BDR-077 — pipeline modes around the dispatcher)
The dispatcher (/seo) runs this agent as a 3-stage pipeline; /harden and
/onboard may still run it single-shot. Parse the MODE line in the prompt:
- **`MODE: collect`** — dispatched `model: "sonnet"` (mechanical/standard
collection; the call-site override takes precedence over the opus pin).
Runs STEP 0-5 ONLY, writes every gathered signal (tech context, tool
availability, live-audit raw results, on-page inventory + sampling
frame) to the run-scoped, gitignored `.audit/seo-signals-<RUNID>.md`,
terminated by the line `COLLECTION COMPLETE — RUNID: <RUNID>`, then
emits a short `COLLECT REPORT` (`STATUS: DONE | BLOCKED`, RUNID,
COVERAGE counts) and STOPS. No scoring, no findings, no bundle.
- **`MODE: judge`** — runs on the opus frontmatter pin (audit judgment).
FIRST loads `.audit/seo-signals-<RUNID>.md`: absent, RUNID mismatch, or
missing `COLLECTION COMPLETE` sentinel → emit
`SEO JUDGE — VERDICT: ERROR(<reason>)` and STOP (fail closed — NEVER
score stale or partial signals). Then runs STEP 6-11 on the signals +
the dispatcher-fed context and emits the scoring blocks + findings +
action plan + triage batches as its report. No bundle, no SEO.md.
- **`MODE: template`** — dispatched `model: "sonnet"`. INPUT: the
dispatcher-fed context + the judge's report VERBATIM (never re-derive a
score or re-judge a finding). Runs STEP 12-14: FIX BUNDLE + sentinel,
report file, envelope.
- **No MODE line** — legacy single-shot: all steps in sequence on the
opus pin (used by /harden narrow-scope and /onboard report-only).
Every mode receives the full dispatcher CONTEXT block (LRN-126 — the
STEP 1-2 business/tech context is consumed by all later steps).
---
## STEP 0 — AUDIT DEPTH
**First action.** If a parent skill (`/seo` dispatcher) passed depth
@@ -743,6 +776,10 @@ Validate:
---
> **MODE BOUNDARY — `MODE: collect` ends at STEP 5**: write the signals
> file + `COLLECTION COMPLETE — RUNID: <RUNID>` terminal line, emit the
> COLLECT REPORT, stop. STEP 6-11 below are `MODE: judge` territory.
## STEP 6 — EXTERNAL PRESENCE AUDIT `[FULL only, local business only]`
**Skip if not a local business** (pure SaaS, content-only → jump to STEP 7).
@@ -1181,6 +1218,10 @@ Do not proceed to STEP 12 until this plan is printed.
---
> **MODE BOUNDARY — `MODE: judge` ends at STEP 11** (scoring + findings +
> plan + batches reported, nothing serialized). STEP 12-14 below are
> `MODE: template` territory, operating on the judge report verbatim.
## STEP 12 — EMIT FIX BUNDLE `[both]`
**You do NOT apply fixes and you do NOT dispatch any sub-agent.** Same
+1
View File
@@ -2,6 +2,7 @@
name: validator-analyzer
description: Web standards audit agent — W3C HTML validity (validator.nu), W3C CSS validity (jigsaw.w3.org), WCAG 2.1 accessibility (axe-core, pa11y, WAVE). Dispatched from /web-validate. Produces scored .claude/audits/VALIDATE.md report with concrete diffs for auto-fixable issues and user actions for judgment-required fixes. Complementary to /harden (security), /seo (indexability), /geo (AI extraction).
tools: Read, Edit, Write, Bash, Grep, Glob, WebFetch
model: sonnet
---
# Validator — W3C + WCAG audit
+63
View File
@@ -0,0 +1,63 @@
#!/usr/bin/env bash
# ctx7-reminder.sh
#
# UserPromptSubmit hook. When the current project uses fast-moving libs
# (lib/fast-libs.sh) it injects ONE reminder per session to consult ctx7
# (find-docs skill) before coding against their APIs, pointing at the
# .ctx7-cache/ state. Closes the ad-hoc-coding gap: find-docs' description
# fires on doc *questions* and ship-feature/init-project pre-fetch, but
# nothing covered a plain "add a useEffect here" prompt (BDR-078; second
# deliberate ctx7 surface, scoped refinement of BDR-053 single-surface).
#
# Soft nudge: always exits 0, never blocks. Stable-tech projects (no
# manifest, or no fast-lib match) stay silent.
set -euo pipefail
input="$(cat)"
field() { # $1=json key — extracted from hook stdin, empty on failure
printf '%s' "$input" | python3 -c \
"import sys,json; print(json.load(sys.stdin).get('$1',''))" \
2>/dev/null || true
}
prompt="$(field prompt)"
case "$prompt" in
'<task-notification>'*) exit 0 ;; # harness turn, not a user request
esac
cwd="$(field cwd)"
[ -n "$cwd" ] || cwd="$PWD"
# Cheap bail-out before any lib work: no manifest → no fast-libs.
[ -f "$cwd/package.json" ] || [ -f "$cwd/requirements.txt" ] \
|| [ -f "$cwd/pyproject.toml" ] || exit 0
# One fire per session: the doctrine holds for the whole session,
# repeating it on every prompt would be token spam.
session_id="$(field session_id)"
sentinel="${TMPDIR:-/tmp}/.ctx7-reminder-${session_id:-nosession}"
[ -e "$sentinel" ] && exit 0
# Resolve the lib next to this hook (repo layout), fall back to the
# installed copy — both paths exist through the link.sh symlinks.
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
libsh="${script_dir}/../lib/fast-libs.sh"
[ -f "$libsh" ] || libsh="${HOME}/.claude/lib/fast-libs.sh"
[ -f "$libsh" ] || exit 0
libs="$(bash "$libsh" detect "$cwd" 2>/dev/null || true)"
[ -n "$libs" ] || exit 0
status="$(bash "$libsh" cache-status "$cwd" 2>/dev/null || true)"
: > "$sentinel" || true
list="$(printf '%s' "$libs" | tr '\n' ' ' | sed 's/ *$//')"
if [ "$status" = "fresh" ]; then
printf '📚 Fast-moving libs in this project (%s) — fresh .ctx7-cache/ present: read the matching cache file before relying on their APIs.\n' "$list"
else
printf '📚 Fast-moving libs in this project (%s) — .ctx7-cache/ %s: consult ctx7 (find-docs skill) before writing code against their APIs. Stable techs need nothing.\n' "$list" "${status:-missing}"
fi
exit 0
+40
View File
@@ -644,6 +644,46 @@ if command -v ctx7 &>/dev/null; then
# (~490 tok/session, job1 F10). Purge it unconditionally so re-runs and
# manual `ctx7 setup` invocations stay rule-free.
rm -f "$HOME/.claude/rules/context7.md"
# BDR-078: re-apply the coverage extension to the generated skill — the
# before-writing-code trigger (description) + the cache-first rule (body).
# The dist is machine-owned (gitignored, regenerated on fresh clones), so
# the durable copy of this patch lives HERE. Idempotent: grep-guarded.
_fd="$HOME/.claude/skills/find-docs/SKILL.md"
if [ -f "$_fd" ] && ! grep -q 'fast-libs.sh detect' "$_fd"; then
if python3 - "$_fd" <<'PY'
import sys
p = sys.argv[1]
s = open(p, encoding="utf-8").read()
DESC = """
Also use BEFORE writing or modifying code that uses a fast-moving library
(anything `bash ~/.claude/lib/fast-libs.sh detect .` reports — React,
Next.js, Prisma, Tailwind, Astro, Svelte…), even when the user asked for
code rather than documentation — unless a fresh `.ctx7-cache/` file already
covers the API involved. Stable technologies (C, C++98, POSIX shell, SQL…)
need no lookup."""
BODY = """
## Cache first
Before any fetch, check the project's `.ctx7-cache/`
(`bash ~/.claude/lib/fast-libs.sh cache-status .`): a fresh (<7 days)
`<lib>*.md` may already answer — read it instead of calling ctx7. When a
`docs` call supports code you are about to write, save the output for the
next consumer:
`npx ctx7@latest docs <id> "<query>" | tee .ctx7-cache/<lib>-<topic>.md`.
"""
i = s.index("\n---", 3) # closing frontmatter fence
s = s[:i] + "\n" + DESC + s[i:]
m = "using the Context7 CLI.\n" # intro line under the H1
j = s.index(m) + len(m) if m in s else len(s)
s = s[:j] + BODY + s[j:]
open(p, "w", encoding="utf-8").write(s)
PY
then
ok "find-docs skill extended (BDR-078 fast-libs trigger + cache-first)"
else
warn "find-docs BDR-078 patch failed — re-run 'make plugin' or patch by hand"
fi
fi
info "Standalone usage: ctx7 docs /vercel/next.js \"middleware\""
fi
+5 -3
View File
@@ -42,9 +42,11 @@ Agent(subagent_type="plan-challenger", description="challenge:<lens>", prompt=""
""")
```
**MODEL (BDR-066):** plan critique is AUDIT JUDGMENT — do NOT pin
`model: "sonnet"`; the challengers inherit the big session model. (The executor
gates stay sonnet; the challenger does not.)
**MODEL (BDR-076, supersedes the BDR-066 inherit):** plan critique is AUDIT
JUDGMENT — the challengers are `model: opus`-pinned in their frontmatter: a big
tier, session-independent, off the session model. The session model (Fable)
keeps only this loop — synthesis, RE-THINK, gate. Never sonnet: that would
silently downgrade the judgment. (The executor gates stay sonnet.)
**Lens framing by `KIND`** (the agent's three lenses, read against the artifact):
- `build-plan` — will it WORK / will it BREAK / is it needlessly COMPLEX.
+13 -8
View File
@@ -17,23 +17,28 @@ and any SIGNIFICANT-gated patch), with the code already committed.
- Orchestrators (ship-feature / init-project): run it BEFORE the FINISH step — otherwise
the doc commit strands outside the merge/PR (the exact bug this fixes). See ORDERING.
doc-syncer runs IN-THREAD (the orchestrator loads it), so the list of files it patched is
already in hand — surfaced as `PATCHED_FILES:` in doc-syncer's OUTPUT, ONE PATH PER LINE.
Pass each line as a SEPARATE argument (see DO step 3).
doc-syncer runs DISPATCHED (BDR-077: `MODE: audit` on opus → dispatcher gate
→ `MODE: patch` on sonnet); its patch-mode report hands the orchestrator BOTH
machine blocks: `PATCHED_FILES:` (ONE PATH PER LINE — pass each line as a
SEPARATE argument, see DO step 3) and `CHANGE SUMMARY` (one line per patched
file — the patch context that used to be in-thread now crosses the dispatch
boundary through this block, LRN-126).
## DO
1. Collect `PATCHED_FILES` — the public-doc paths doc-syncer wrote this run (its OUTPUT
block, ONE PATH PER LINE). Empty → nothing to commit; the helper no-ops.
2. Compose — from the patch context the AGENT holds (doc-syncer ran in-thread, so the
agent knows exactly what changed) — BOTH artifacts:
2. Compose — from doc-syncer's `CHANGE SUMMARY` block (the patcher held the
patch context and reported it; a dispatched patcher with NO summary block
in its report = incomplete report, re-dispatch rather than invent) —
BOTH artifacts:
- the COMMIT MESSAGE, repo style `docs: <summary> — <flow>`
(`docs: README features + USAGE flags — ship-feature dark-mode`);
- the CHANGE SUMMARY for the rc 0 surface (e.g. "README features section + USAGE
--export flag").
Both are the AGENT's to write — the helper produces NEITHER (its only stdout is the
hash). This is the load-bearing point of the visible surface: see the rc 0 row.
--export flag") — derived from the block, never a bare file count.
Both are the ORCHESTRATOR's to write — the helper produces NEITHER (its only stdout
is the hash). This is the load-bearing point of the visible surface: see the rc 0 row.
3. Commit surgically via the helper, passing EXACTLY the patched files — each path as a
SEPARATE argument (split `PATCHED_FILES` on NEWLINES only), capturing the hash:
+65
View File
@@ -0,0 +1,65 @@
#!/usr/bin/env bash
# fast-libs.sh — single source of truth for "fast-moving library" detection.
#
# Fast-moving = API churns faster than model training data (React, Next.js,
# Prisma…) → consult ctx7 (find-docs) before coding against it. Stable techs
# (C, C++98, POSIX sh, SQL…) never match: no ctx7 needed (BDR-078).
#
# Consumers: hooks/ctx7-reminder.sh, /ship-feature STEP 0c, /init-project
# STEP 5c, /onboard STEP 3.5, feater/bugfixer executor briefs.
#
# Verbs:
# fast-libs.sh detect [dir] detected libs, one/line; exit 1 if none
# fast-libs.sh cache-status [dir] fresh|stale|missing; exit 0 only if fresh
set -euo pipefail
# Exact npm dependency keys (unscoped). Anchored full-key match — "react"
# must not drag react-icons along.
NPM_EXACT='next|react|react-dom|react-native|expo|prisma|supabase'
NPM_EXACT+='|drizzle-orm|astro|svelte|vue|nuxt|tailwindcss|vite|next-auth'
NPM_EXACT+='|motion|framer-motion|ai|openai|langchain|remix|fastify'
# Scoped npm orgs (@org/…).
NPM_SCOPED='prisma|supabase|astrojs|sveltejs|tanstack|clerk|anthropic-ai'
NPM_SCOPED+='|langchain|remix-run|nestjs|tailwindcss'
# Python distributions (requirements.txt / pyproject.toml).
PY_LIBS='fastapi|pydantic|sqlalchemy|langchain'
CACHE_MAX_AGE_DAYS=7
npm_fast_libs() { # $1=dir — matching dependency keys, one per line
[ -f "$1/package.json" ] || return 0
jq -r '((.dependencies // {}) + (.devDependencies // {})) | keys[]' \
"$1/package.json" 2>/dev/null \
| grep -E "^(${NPM_EXACT})\$|^@(${NPM_SCOPED})/" || true
}
py_fast_libs() { # $1=dir — matching distributions, one per line
grep -hoiE "\b(${PY_LIBS})\b" \
"$1/requirements.txt" "$1/pyproject.toml" 2>/dev/null \
| tr '[:upper:]' '[:lower:]' | LC_ALL=C sort -u || true
}
detect() { # $1=dir — union, sorted unique; exit 1 when empty
local libs
# LC_ALL=C: deterministic order whatever the caller's locale.
libs="$(printf '%s\n%s\n' "$(npm_fast_libs "$1")" "$(py_fast_libs "$1")" \
| sed '/^$/d' | LC_ALL=C sort -u)"
[ -n "$libs" ] || return 1
printf '%s\n' "$libs"
}
cache_status() { # $1=dir — fresh|stale|missing; exit 0 only when fresh
[ -d "$1/.ctx7-cache" ] || { echo missing; return 1; }
if [ -n "$(find "$1/.ctx7-cache" -name '*.md' \
-mtime "-${CACHE_MAX_AGE_DAYS}" -print -quit 2>/dev/null)" ]; then
echo fresh; return 0
fi
echo stale; return 1
}
case "${1:-}" in
detect) detect "${2:-.}" ;;
cache-status) cache_status "${2:-.}" ;;
*) echo "usage: fast-libs.sh detect|cache-status [dir]" >&2; exit 2 ;;
esac
+10
View File
@@ -35,3 +35,13 @@ yet rewritten) — that is why the self-check exists alongside it.
then end the turn. No later step runs, no agent is dispatched, nothing is
edited.
## 4. Dispatch tiers (BDR-077 — no inherit)
The gate guards the MAIN loop only. Dispatched work NEVER inherits the
session model: typed agents run on their frontmatter pin; built-ins
(general-purpose / Explore / Plan) carry an explicit `model=` at every call
site — `model: "fable"` when the child performs reflection/orchestration on
the main loop's behalf (skill-runners), otherwise its complexity tier
(opus = dispatched judgment, sonnet = execution/collection, haiku = short
mechanical probes).
+90
View File
@@ -0,0 +1,90 @@
# Plugin gate — shared consumer include (plugin-check, onboard, init-project, ship-feature STEP 0)
Runs in the CONSUMER'S MAIN LOOP. The detection and the reasoning are
dispatched (BDR-077 tiers); the validation checkpoint, the report
presentation, and the apply gate live HERE — a dispatched agent can neither
ask the user nor safely mutate plugin state.
## 1. PROBE (dispatch — sonnet)
```
Agent(subagent_type="plugin-probe", description="plugin gate — probe",
prompt="Run your probes from <PROJECT_ROOT>. Emit the PROBE REPORT.")
```
## 2. VALIDATION CHECKPOINT (main loop — between probe and reasoner)
Validate the PROBE REPORT before any reasoning:
- `EXTERNAL` non-empty AND each listed plugin's directory appears under
`CHECKPOINT plugin-dirs`.
- At least one project signal present (MANIFESTS / FRAMEWORK-DEPS /
TSX-JSX-COUNT > 0 / DOCKER-COUNT > 0 / EMBEDDED hits). Else print
`⚠️ No project signals detected — recommendations will be conservative.`
and continue.
- `CHECKPOINT toggle-script=UNAVAILABLE` → print `⚠️ toggle script
unavailable — recommendations will be advisory only, no auto-activation.`
and SKIP step 5 (apply) entirely.
- PROBE REPORT missing/unparsable → retry the probe ONCE fresh; a 2nd
failure → STOP and surface (never reason over invented detection).
## 3. REASON (dispatch — opus)
```
Agent(subagent_type="plugin-advisor", description="plugin gate — reason",
prompt="""
REQUEST: <the user's request / project description, verbatim>
PROBE REPORT (ground truth — do not re-detect):
<the full PROBE REPORT from step 1>
""")
```
## 4. PRESENT + BLOCKING GATE (main loop)
Show the returned PLUGIN CHECK block.
- `ACTION REQUIRED? YES` → offer: A) fix plugins B) type "force". STOP until
answered.
- OK → print `✅ Plugin check passed — [active plugins] — complexity: <score>%`.
## 5. APPLY GATE (main loop — only when the flow auto-activates)
If any plugin has ⚡ ENABLE status:
1. List the changes:
```
PROPOSED CHANGES:
⚡ Enable ui-ux-pro-max (frontend detected, complexity 65%)
⚡ Pre-fetch ctx7 docs for next.js, prisma
Apply these changes? (yes / no / customize)
```
2. "yes" → apply via the exact commands the advisor emitted. "customize" →
user picks. "no" → proceed with current config.
**Never auto-activate without showing the list and getting confirmation.**
### Rollback on partial failure
Track each toggle; roll back the partial set rather than leave a
half-applied configuration:
```bash
applied=()
for change in "${PROPOSED_CHANGES[@]}"; do
if bash "$HOME/.claude/lib/toggle-external.sh" enable "$change"; then
applied+=("$change")
else
echo "❌ failed to enable $change — rolling back ${#applied[@]} prior change(s)"
for prior in "${applied[@]}"; do
bash "$HOME/.claude/lib/toggle-external.sh" disable "$prior" \
|| echo "⚠️ rollback of $prior also failed — manual cleanup required: see ~/.claude/plugins/cache"
done
exit 1
fi
done
```
Surface: `✅ Applied N change(s).` — or on failure:
```
⚠️ Toggle failed at change <name>. Rolled back the N prior change(s).
To inspect manually: ls ~/.claude/plugins/cache; bash ~/.claude/lib/toggle-external.sh list
Re-run /plugin-check after fixing the underlying cause (e.g. permissions).
```
+52
View File
@@ -0,0 +1,52 @@
#!/usr/bin/env bash
# lib/tests/fast-libs.test.sh — fast-libs.sh verbs + ctx7-reminder hook (BDR-078)
set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
L="$ROOT/lib/fast-libs.sh"
H="$ROOT/hooks/ctx7-reminder.sh"
pass=0; fail=0
check() { if [ "$2" = "$3" ]; then pass=$((pass+1)); else fail=$((fail+1));
printf 'FAIL %s: got[%s] want[%s]\n' "$1" "$2" "$3"; fi; }
tmp="$(mktemp -d)"; trap 'rm -rf "$tmp"' EXIT
# --- detect: JS fast-libs matched, stable deps ignored ---
mkdir -p "$tmp/js"
cat > "$tmp/js/package.json" <<'EOF'
{"dependencies":{"react":"^19","express":"^5","@tanstack/react-query":"^5"},
"devDependencies":{"vite":"^6","lodash":"^4"}}
EOF
check T1-js-detect "$(bash "$L" detect "$tmp/js" | tr '\n' ' ')" \
"@tanstack/react-query react vite "
# react-icons must NOT ride the react match (anchored full-key)
mkdir -p "$tmp/near"
printf '{"dependencies":{"react-icons":"^5","express":"^5"}}' \
> "$tmp/near/package.json"
check T2-near-miss "$(bash "$L" detect "$tmp/near" >/dev/null 2>&1; echo $?)" 1
# --- detect: python manifest + stable-tech project (exit 1) ---
mkdir -p "$tmp/py"
printf 'fastapi==0.115\nrequests>=2\n' > "$tmp/py/requirements.txt"
check T3-py-detect "$(bash "$L" detect "$tmp/py")" "fastapi"
mkdir -p "$tmp/cpp"
check T4-none "$(bash "$L" detect "$tmp/cpp" >/dev/null 2>&1; echo $?)" 1
# --- cache-status: missing / fresh / stale ---
check T5-missing "$(bash "$L" cache-status "$tmp/js" || true)" missing
mkdir -p "$tmp/js/.ctx7-cache"; touch "$tmp/js/.ctx7-cache/react-core.md"
check T6-fresh "$(bash "$L" cache-status "$tmp/js")" fresh
touch -d '10 days ago' "$tmp/js/.ctx7-cache/react-core.md"
check T7-stale "$(bash "$L" cache-status "$tmp/js" || true)" stale
# --- hook: fires once per session, silent on stable projects ---
hook() { printf '{"prompt":"add a hook","session_id":"%s","cwd":"%s"}' \
"$1" "$2" | TMPDIR="$tmp" bash "$H"; }
check H1-fires "$(hook s1 "$tmp/js" | grep -c 'Fast-moving')" 1
check H2-once "$(hook s1 "$tmp/js" | wc -l)" 0
check H3-cpp-quiet "$(hook s2 "$tmp/cpp" | wc -l)" 0
check H4-notif-quiet \
"$(printf '{"prompt":"<task-notification>x","session_id":"s3","cwd":"%s"}' \
"$tmp/js" | TMPDIR="$tmp" bash "$H" | wc -l)" 0
printf 'PASS=%s FAIL=%s\n' "$pass" "$fail"; [ "$fail" -eq 0 ]
+107 -8
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env bash
# lib/tests/model-routing.test.sh — census: gate wiring + pins + executor shape (BDR-066)
# lib/tests/model-routing.test.sh — census: gate wiring + pins + executor shape (BDR-066, BDR-076)
set -u
R="$(cd "$(dirname "$0")/../.." && pwd)"
pass=0; fail=0
@@ -22,7 +22,7 @@ has "agents/feater.md" 'model: sonnet'
has "agents/hotfixer.md" 'model: sonnet'
has "agents/verifier.md" 'model: sonnet'
has "agents/security-auditor.md" 'model: sonnet'
fm_lacks "agents/analyzer.md" 'model:'
has "agents/analyzer.md" 'model: opus'
# 4) /feat executor shape
has "skills/feat/SKILL.md" 'subagent_type="feater"'
has "skills/feat/SKILL.md" 'verify-secure-loop.md'
@@ -54,17 +54,116 @@ lacks "agents/handover-doc-writer.md" 'AskUserQuestion'
lacks "agents/handover-doc-writer.md" 'Agent('
has "agents/client-handover-writer.md" 'subagent_type="handover-doc-writer"'
# 10) post-merge edge fixes (ronde): F1 feater applier carve-out, F2 /refactor
# dispatch + pin, F3 /analyze gated (in loop 1), F4 interviewer un-pinned,
# F5 audit agents' ABSENT pin locked (a stray sonnet pin would silently
# downgrade a live audit even though the skill's gate passed)
# dispatch + pin, F3 /analyze gated (in loop 1)
has "agents/feater.md" 'Applier path'
has "skills/refactor/SKILL.md" 'subagent_type="refactorer"'
has "agents/refactorer.md" 'model: sonnet'
fm_lacks "agents/seo-analyzer.md" 'model:'
fm_lacks "agents/geo-analyzer.md" 'model:'
fm_lacks "agents/validator-analyzer.md" 'model:'
# 11) BDR-076/077 — session model = orchestration + inline reflection ONLY.
# Dispatched judgment agents pinned OPUS. validator-analyzer TIERED DOWN
# to sonnet (W3 — deterministic validator-runner + fixed deduction
# tables, no deep judgment; approved plan). Inline-load-only agents
# (interviewer, client-handover-writer) STAY unpinned: they run IN the
# main loop, a frontmatter pin there is inert and misleads.
has "agents/seo-analyzer.md" 'model: opus'
has "agents/geo-analyzer.md" 'model: opus'
has "agents/validator-analyzer.md" 'model: sonnet'
has "agents/plan-challenger.md" 'model: opus'
fm_lacks "agents/client-handover-writer.md" 'model:'
fm_lacks "agents/interviewer.md" 'model:'
has "skills/onboard/SKILL.md" 'model="opus"'
has "skills/tour/SKILL.md" 'model="opus"'
has "lib/challenge-plan.md" 'BDR-076'
# 12) BDR-077 W1 — no-inherit: skill-runner children pinned fable at every
# call site; code-review dispatches carry opus; doctrine in model-gate.
# (fable dispatch alias spike-verified 2026-07-19: resolves
# claude-fable-5, enum-validated, loud failure — never silent fallback)
has "agents/client-handover-writer.md" 'model: "fable"'
has "skills/ship-feature/SKILL.md" 'model: "opus"'
has "skills/init-project/SKILL.md" 'model: "opus"'
has "lib/model-gate.md" 'model: "fable"'
lacks "lib/model-gate.md" 'model: "sonnet" in the Agent call'
# 13) BDR-077 W2 — plugin split: probe (sonnet, facts only) + advisor
# reasoner (opus, PROBE REPORT is ground truth, fail-closed); gate
# include owns checkpoint + apply; 4 consumers run the include, none
# inline-loads the advisor anymore
has "agents/plugin-probe.md" 'model: sonnet'
lacks "agents/plugin-probe.md" 'AskUserQuestion'
has "agents/plugin-advisor.md" 'model: opus'
has "agents/plugin-advisor.md" 'PROBE REPORT'
lacks "agents/plugin-advisor.md" 'PHASE 1 — DETECT'
has "lib/plugin-gate.md" 'subagent_type="plugin-probe"'
has "lib/plugin-gate.md" 'subagent_type="plugin-advisor"'
for s in plugin-check onboard init-project ship-feature; do
has "skills/$s/SKILL.md" 'lib/plugin-gate.md'
# shellcheck disable=SC2016 # literal $HOME wanted: matching the exact inline-load string
lacks "skills/$s/SKILL.md" 'Load `$HOME/.claude/agents/plugin-advisor.md`'
done
# 14) BDR-077 W2/S2 — doc pipeline: ONE agent, TWO modes around the
# dispatcher's gate (audit = opus via call-site override — documented
# precedence over the sonnet pin; patch = sonnet pin). Gate hoisted out
# of the agent (a dispatched agent cannot ask); CHANGE SUMMARY crosses
# the dispatch boundary into doc-commit (LRN-126); scaffolder carries no
# doc step; no consumer inline-loads doc-syncer anymore.
has "agents/doc-syncer.md" 'MODE: audit'
has "agents/doc-syncer.md" 'MODE: patch'
has "agents/doc-syncer.md" 'CHANGE SUMMARY'
has "agents/doc-syncer.md" 'DISPATCHER PROTOCOL'
has "lib/doc-commit.md" 'CHANGE SUMMARY'
has "skills/doc/SKILL.md" 'model="opus"'
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
# 15) BDR-077 W2 — last inline execution converted: scaffolder + onboarder
# are DISPATCHED (pins live); their gates/arbitration stay in the
# orchestrator loop
has "skills/init-project/SKILL.md" 'subagent_type="scaffolder"'
has "skills/onboard/SKILL.md" 'subagent_type="onboarder"'
# shellcheck disable=SC2016
lacks "skills/init-project/SKILL.md" 'Load `$HOME/.claude/agents/scaffolder.md`'
# shellcheck disable=SC2016
lacks "skills/onboard/SKILL.md" 'Load `$HOME/.claude/agents/onboarder.md`'
# 16) BDR-077 W3 — commit-changer per-mode override: propose = opus at the
# call site (documented precedence over the sonnet pin), apply = pin
has "skills/commit-change/SKILL.md" 'model="opus"'
has "agents/commit-changer.md" 'MODE: propose'
has "agents/commit-changer.md" 'model: sonnet'
# 17) BDR-077 W4 — handover two-mode: synthesize = opus at the call site
# (STEP 9/10/12 → run-scoped .audit/ draft + DRAFT COMPLETE sentinel),
# render = sonnet pin (STEP 13-16, fail-closed on absent/mismatched
# draft). Name + dispatch-string locks of §9 survive untouched.
has "agents/handover-doc-writer.md" 'MODE: synthesize'
has "agents/handover-doc-writer.md" 'MODE: render'
has "agents/handover-doc-writer.md" 'DRAFT COMPLETE'
has "agents/client-handover-writer.md" 'MODE: synthesize'
has "agents/client-handover-writer.md" 'handover-doc-writer", model="opus"'
# 18) BDR-077 W5 — seo/geo 3-mode pipelines: collect/template = sonnet at
# the call site, judge = opus PIN (fail-safe direction: a forgotten
# override over-tiers, never downgrades judgment). Run-scoped signals
# handoff + completeness sentinel + fail-closed judge + dispatcher
# ERROR contract (mute/ERROR judge never carried into templating).
# Body text unmoved — seo-data.test.sh fetch-wiring locks survive.
has "agents/seo-analyzer.md" 'MODE: collect'
has "agents/seo-analyzer.md" 'MODE: judge'
has "agents/seo-analyzer.md" 'MODE: template'
has "agents/seo-analyzer.md" 'COLLECTION COMPLETE'
has "agents/geo-analyzer.md" 'MODE: collect'
has "agents/geo-analyzer.md" 'MODE: judge'
has "agents/geo-analyzer.md" 'MODE: template'
has "agents/geo-analyzer.md" 'COLLECTION COMPLETE'
has "skills/seo/SKILL.md" 'MODE: collect'
has "skills/seo/SKILL.md" 'seo-analyzer", model="sonnet"'
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 ]
+7 -1
View File
@@ -250,7 +250,7 @@
"disableBypassPermissionsMode": "disable",
"additionalDirectories": []
},
"model": "opus[1m]",
"model": "claude-fable-5[1m]",
"hooks": {
"SessionStart": [
{
@@ -281,6 +281,12 @@
"command": "bash ~/.claude/hooks/design-toolchain-reminder.sh",
"timeout": 5,
"statusMessage": "Checking design signals..."
},
{
"type": "command",
"command": "bash ~/.claude/hooks/ctx7-reminder.sh",
"timeout": 5,
"statusMessage": "Checking fast-libs..."
}
]
}
+10 -3
View File
@@ -225,9 +225,16 @@ Parse the `BUGFIX-EXEC REPORT`:
## STEP 7 — DOC SYNC (automatic)
Load `$HOME/.claude/agents/doc-syncer.md`.
Execute in automatic mode:
`auto-mode scope: <list of files modified during this session>`
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
sonnet pin, gate HERE):
1. `Agent(subagent_type="doc-syncer", model="opus")` — `MODE: audit` +
`auto-mode scope: <list of files modified during this session>`.
2. Silence (NONE) → done. `[MINOR]` PATCH PLAN → re-dispatch
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan
verbatim (no gate — auto behavior preserved; a `SHAPE ESCALATION` in
its report comes back here, gated as SIGNIFICANT).
3. SIGNIFICANT → gate here (`Apply? yes / no / select`), then
`MODE: patch` with the approved subset.
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
+5 -3
View File
@@ -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:
+10 -4
View File
@@ -18,7 +18,8 @@ allowed-tools:
# /commit-change — propose → confirm → apply dispatcher
Grouping and committing both run on the sonnet-pinned `commit-changer`
Grouping (propose, `model="opus"` override — judgment) and committing
(apply, sonnet pin — mechanical) both run on the dispatched `commit-changer`
subagent (dispatch makes the pin effective). No inline reflection happens
in this dispatcher to protect, so there is no model gate. This dispatcher
owns the two approval gates that used to live inside the subagent:
@@ -52,11 +53,15 @@ protected branch.
## STEP 1 — Propose
```
Agent(subagent_type="commit-changer")
Agent(subagent_type="commit-changer", model="opus")
prompt: "MODE: propose
$ARGUMENTS"
```
(`model="opus"` — BDR-077: propose = narrative reconstruction + capitalize
routing, judgment tier; the call-site override takes precedence over the
sonnet frontmatter pin. Apply, STEP 4, stays on the pin.)
Read the returned `COMMIT PLAN` + `EDGE CASES` + `CAPITALIZE CANDIDATES`,
terminated by `READY TO APPLY — awaiting dispatcher confirmation`.
@@ -77,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
+23 -8
View File
@@ -18,13 +18,28 @@ allowed-tools:
- Agent
---
Dispatch the doc-syncer as a subagent so its `model: sonnet` pin takes
effect (doc-sync = execution, not the session's big model):
Run the two-mode doc pipeline (BDR-077 — audit judgment on opus, patch on
the sonnet pin, the validation gate in THIS loop; a dispatched agent cannot
hold a gate):
Agent(subagent_type="doc-syncer")
prompt: "Audit + sync public docs for this project. Context from the user:
$ARGUMENTS. Report PATCHED_FILES and a summary — do NOT commit."
1. AUDIT — dispatch:
`Agent(subagent_type="doc-syncer", model="opus")`
prompt: "MODE: audit. Audit public docs for this project. Context from
the user: $ARGUMENTS. Emit the DOC SYNC REPORT + PATCH PLAN — no writes."
Then commit the patched docs from THIS loop per `$HOME/.claude/lib/doc-commit.md`
(surgical: only doc-syncer's PATCHED_FILES, never `.claude/`/`CLAUDE.md`,
no-op if nothing patched).
2. GATE — present the report and run the DOC SYNC — VALIDATION GATE from
the agent's DISPATCHER PROTOCOL (AUTO yes/select/cancel; HUMAN, CREATE,
CLEAN per-item; README CREATE has no skip). Wait for explicit approval.
`DOC SYNC: all docs current` → stop here.
3. PATCH — re-dispatch:
`Agent(subagent_type="doc-syncer")` (sonnet pin)
prompt: "MODE: patch." + the APPROVED PATCH PLAN verbatim (approved item
lines + rendered drafts for approved CREATE items). A `SHAPE ESCALATION`
in its report → re-gate the named set here, then re-dispatch patch with
the kept subset.
4. COMMIT — from THIS loop per `$HOME/.claude/lib/doc-commit.md` (surgical:
only the report's `PATCHED_FILES`, summary composed from its
`CHANGE SUMMARY` block, never `.claude/`/`CLAUDE.md`, no-op if nothing
patched).
+11 -4
View File
@@ -186,7 +186,7 @@ feat(<scope>): <what was added>
If the feature touched multiple concerns (e.g., feature + config +
test), consider splitting into 2-3 atomic commits grouped by logical
unit — or run `/commit-change` on the pending work (it dispatches the
sonnet commit-changer; never inline-load the bare agent, it is now a
commit-changer (propose opus / apply sonnet, BDR-077); never inline-load the bare agent, it is now a
propose/apply executor).
Print summary:
@@ -200,9 +200,16 @@ VERIFIED : <what was checked>
## STEP 6 — DOC SYNC (automatic)
Load `$HOME/.claude/agents/doc-syncer.md`.
Execute in automatic mode:
`auto-mode scope: <list of files modified during this session>`
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
sonnet pin, gate HERE):
1. `Agent(subagent_type="doc-syncer", model="opus")` — `MODE: audit` +
`auto-mode scope: <list of files modified during this session>`.
2. Silence (NONE) → done. `[MINOR]` PATCH PLAN → re-dispatch
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan
verbatim (no gate — auto behavior preserved; a `SHAPE ESCALATION` in
its report comes back here, gated as SIGNIFICANT).
3. SIGNIFICANT → gate here (`Apply? yes / no / select`), then
`MODE: patch` with the approved subset.
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
+40 -16
View File
@@ -36,26 +36,50 @@ terminated by `READY TO APPLY — awaiting dispatcher confirmation`, and this
skill applies it. Applying from here (one dispatch level, no nested spawn)
is what makes fixes land on any Claude Code version.
## STEP 1 — Dispatch geo-analyzer (audit + bundle)
## STEP 1 — Run the geo pipeline (collect → judge → template, BDR-077)
Gather depth + business context HERE first (ask the user in this loop if
needed — a dispatched agent cannot ask). Mint `RUNID=$(date +%s)-geo`.
Pass the same CONTEXT block ($ARGUMENTS + gathered context) VERBATIM to
every phase (LRN-126). Clean `.audit/geo-signals-<RUNID>.md` after apply.
**A — collect (sonnet):**
```
Agent(subagent_type="geo-analyzer", model="sonnet")
prompt: "MODE: collect
RUNID: <RUNID>
Dispatched from /geo. Context: <CONTEXT>
Execute STEP 0-5 per your spec, write the signals file + COLLECTION
COMPLETE sentinel, emit the COLLECT REPORT, stop."
```
**B — judge (opus pin, no override):**
```
Agent(subagent_type="geo-analyzer")
prompt: """
Dispatched from /geo. Execute your full spec at
~/.claude/agents/geo-analyzer.md (STEP 0 onward — gather depth + business
context as needed; if you must ask the user, ask and I relay).
prompt: "MODE: judge
RUNID: <RUNID>
Context: <CONTEXT>
Load .audit/geo-signals-<RUNID>.md (fail closed per your spec), run STEP
6-12, report scoring + findings + action plan + triage batches."
```
**ERROR CONTRACT:** `GEO JUDGE — VERDICT: ERROR(…)` or a mute judge →
STOP: no template, no apply. Surface verbatim, retry ONCE with a fresh
collect+judge, then escalate. Never carry a mute/ERROR judge into
templating.
Produce your report:
- If .claude/audits/SEO.md already exists → merge findings into its
§7 — Optimisation GEO / IA.
- Else write .claude/audits/GEO.md.
Then emit the `## FIX BUNDLE` (STEP 13) terminated by the verbatim
`READY TO APPLY — awaiting dispatcher confirmation` sentinel. Do NOT apply
any fix and do NOT dispatch any sub-agent — /geo applies your bundle.
$ARGUMENTS
"""
**C — template (sonnet):**
```
Agent(subagent_type="geo-analyzer", model="sonnet")
prompt: "MODE: template
Context: <CONTEXT>
JUDGE REPORT (verbatim, ground truth — never re-derive a score):
<the judge report>
Run STEP 13-15. Produce your report: if .claude/audits/SEO.md already
exists → merge findings into its §7 — Optimisation GEO / IA; else write
.claude/audits/GEO.md. Then emit the `## FIX BUNDLE` terminated by the
verbatim `READY TO APPLY — awaiting dispatcher confirmation` sentinel.
Do NOT apply any fix and do NOT dispatch any sub-agent — /geo applies
your bundle."
```
## STEP 1b — CHALLENGE THE FIX BUNDLE (advisory, before apply)
+10 -3
View File
@@ -174,9 +174,16 @@ Parse the `HOTFIX-EXEC REPORT`:
## STEP 5 — DOC SYNC (automatic)
Load `$HOME/.claude/agents/doc-syncer.md`.
Execute in automatic mode:
`auto-mode scope: <list of files modified during this session>`
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
sonnet pin, gate HERE):
1. `Agent(subagent_type="doc-syncer", model="opus")` — `MODE: audit` +
`auto-mode scope: <list of files modified during this session>`.
2. Silence (NONE) → done. `[MINOR]` PATCH PLAN → re-dispatch
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan
verbatim (no gate — auto behavior preserved; a `SHAPE ESCALATION` in
its report comes back here, gated as SIGNIFICANT).
3. SIGNIFICANT → gate here (`Apply? yes / no / select`), then
`MODE: patch` with the approved subset.
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
ONLY the files doc-syncer patched (its `PATCHED_FILES` output), never `git add -A`, never
+31 -7
View File
@@ -36,7 +36,8 @@ so the user does not assume Claude has hung.
---
## STEP 0 — PLUGIN CHECK + AUTO-ACTIVATE
Load `$HOME/.claude/agents/plugin-advisor.md`. Feed request.
Run `$HOME/.claude/lib/plugin-gate.md`. Feed request (dispatch plugin-probe →
checkpoint → dispatch plugin-advisor; gates stay in this loop — BDR-077).
- ACTION REQUIRED → show RECOMMENDATIONS block, offer: A) fix plugins B) type "force". STOP.
- PROPOSED CHANGES exist → show list, ask "Apply? (yes / no / customize)". Apply on confirm.
- OK → `✅ Plugin check passed — [active plugins] — complexity: <score>%`, continue.
@@ -91,15 +92,31 @@ contract, each tagged `[gated <date>]`. STEP 9's verifier judges against this
enriched contract.
## STEP 5 — SCAFFOLD
Load `$HOME/.claude/agents/scaffolder.md`. Pass: BRIEF + DESIGN + `~/.claude/templates/project-CLAUDE.md` + `~/.claude/CLAUDE.md`.
Dispatch `Agent(subagent_type="scaffolder")` (pin sonnet, effort high —
BDR-077 : le design est CLOS au gate #1, le scaffold est de l'exécution,
plus jamais inline sur le modèle de session). Pass IN THE PROMPT (LRN-126 —
every field the scaffolder consumes crosses the dispatch): BRIEF (verbatim)
+ DESIGN (verbatim) + paths `~/.claude/templates/project-CLAUDE.md` +
`~/.claude/CLAUDE.md`. A STOP (missing input) comes back as its report —
resolve here, re-dispatch. The ~30s liveness pings are THIS loop's job
while waiting.
Creates: CLAUDE.md, `.claude/settings.json`, `.claudeignore`, `.gitignore`, `.env.example`, empty entry points. NO README, NO features, NO `.claude/tasks/` or `.claude/memory/` (not bootstrapped by this flow — copy from `~/.claude/templates/memory/` manually if wanted before STEP 10b's memory commit).
Verify: `git init` + build passes.
## STEP 5b — CREATE README
Load `$HOME/.claude/agents/doc-syncer.md` (AUTO MODE, scope: full project). README.md missing → its README bootstrap creates it. No stop.
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.):
If `fast-libs` signal was detected in STEP 0 — single source of truth:
`bash ~/.claude/lib/fast-libs.sh detect .` (Next.js, React, Prisma,
Supabase, Drizzle… — BDR-078):
1. Create `.ctx7-cache/` directory in project root.
2. For each detected fast-lib, fetch core docs:
```bash
@@ -223,7 +240,10 @@ against the founding contract. Distinct axis from STEP 10 code review
([[LRN-095]]) — both run.
## STEP 10 — CODE REVIEW
Invoke `superpowers:requesting-code-review`. Fix all CRITICAL before proceeding.
Invoke `superpowers:requesting-code-review`. **Model routing (BDR-077):** the
review subagent it dispatches MUST carry `model: "opus"` in the Agent call —
craft review is dispatched judgment, never inherited from the session. Fix
all CRITICAL before proceeding.
## STEP 10b — CAPITALIZE FOUNDING DECISIONS (memory registries)
A greenfield's founding architecture decisions are the highest-value BDRs — the
@@ -282,8 +302,12 @@ 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).
Load `$HOME/.claude/agents/doc-syncer.md` (AUTO MODE, scope: files changed this session).
Detect drift, update cmds/vars/structure, add recent changes entry.
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.
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
ONLY the files doc-syncer patched (its `PATCHED_FILES` output, one path per line → one argv
+21 -12
View File
@@ -21,7 +21,7 @@ $ARGUMENTS
## STEP 0 — PLUGIN CHECK + AUTO-ACTIVATE
Load `$HOME/.claude/agents/plugin-advisor.md` with hint "onboarding existing project + $ARGUMENTS".
Run `$HOME/.claude/lib/plugin-gate.md` with hint "onboarding existing project + $ARGUMENTS" (dispatch plugin-probe → checkpoint → dispatch plugin-advisor → gates in this loop, BDR-077).
- ACTION REQUIRED → show RECOMMENDATIONS block, offer: A) apply recos B) type "force". STOP.
- PROPOSED CHANGES exist → show list, ask "Apply? (yes / no / customize)". Apply on confirm.
@@ -89,7 +89,11 @@ STOP. La réponse détermine si STEP 1 tourne une fois (A) ou N fois (C) ou avec
## STEP 2 — BASELINE CONFIG (onboarder agent)
Load `$HOME/.claude/agents/onboarder.md`. Passer un BRIEF minimal issu du filesystem scan :
Dispatch `Agent(subagent_type="onboarder")` (pin sonnet — BDR-077 : config
templating = exécution, plus jamais inline sur le modèle de session). Un
BLOCAGE (clé manquante, CLAUDE.md existant) revient en rapport — l'agent ne
peut pas te demander ; TU arbitres ici puis re-dispatches. Passer un BRIEF
minimal issu du filesystem scan :
- `archetype` (depuis STEP 1)
- `project_name` (depuis package.json/pyproject.toml/README.md/dir name)
- `stack` (depuis manifests détectés)
@@ -203,13 +207,10 @@ ls .ctx7-cache/ 2>/dev/null
```
### Détection fast-libs
Parse manifests selon l'archétype :
- **nextjs-app-router** → chercher : next, react, prisma, @supabase/*, drizzle-orm, next-auth, @clerk/*
- **react-spa** → chercher : react, @tanstack/*, zustand, jotai
- **rest-api-node** → chercher : fastify, @nestjs/*, prisma, drizzle-orm
- **rest-api-python** → chercher : fastapi, pydantic, sqlalchemy (si ≥ 2.0)
- **astro-static** → chercher : astro, @astrojs/*
- **wordpress / cli-tool / library / dotfiles-meta / static-html** → souvent aucune fast-lib, audit léger
Source unique : `bash ~/.claude/lib/fast-libs.sh detect .` (deps JS/TS via
package.json + Python via requirements/pyproject — liste centralisée,
BDR-078). Archétypes wordpress / cli-tool / library / dotfiles-meta /
static-html → souvent aucune fast-lib, audit léger.
### Vérification cache
Pour chaque fast-lib détectée :
@@ -354,7 +355,7 @@ Lire le bloc `audit_stack:` du fichier `~/.claude/lib/project-archetypes/<archet
| Entry | Action | Livraison |
|---|---|---|
| `analyze` | Déjà fait en STEP 5 | L3a |
| `code-clean` | Spawn subagent `general-purpose` (audit-only, inherits session = big model) | L3a |
| `code-clean` | Spawn subagent `general-purpose` (audit-only, `model="opus"` — BDR-076: dispatched audits off the session model) | L3a |
| `cso` | Si gstack ON → Skill(cso). Sinon → Agent general-purpose avec checklist OWASP + deps audit | L3a |
| `doc` | Spawn subagent `doc-syncer` (auto-mode OFF, report-only) | L3a |
| `seo` | Subagents seo-analyzer + geo-analyzer en parallèle | L3b |
@@ -370,7 +371,8 @@ Lancer EN PARALLÈLE (un seul message, plusieurs Agent calls) les audits corresp
```
Agent(
subagent_type="general-purpose",
description="Onboard — code-clean audit only (read-only, big session model)",
model="opus",
description="Onboard — code-clean audit only (read-only, opus)",
prompt="""
AUDIT-ONLY mode — NO fixes, NO refactoring, NO file modifications.
Target: <PROJECT_ROOT>. ARCHETYPE: <archetype>.
@@ -406,6 +408,7 @@ bash $HOME/.claude/lib/toggle-external.sh list 2>/dev/null | grep -E "^gstack\s+
```
Agent(
subagent_type="general-purpose",
model="opus",
description="Onboard — security audit fallback (archetype-adaptive)",
prompt="""
READ-ONLY security audit. No file modifications.
@@ -529,9 +532,11 @@ flux de dev sont deux formes distinctes ([[BDR-050]] pipeline dev ≠ audit).
```
Agent(
subagent_type="doc-syncer",
model="opus",
description="Onboard — doc drift audit only",
prompt="""
REPORT-ONLY mode — NO edits, NO auto-sync.
MODE: audit — REPORT-ONLY, NO edits, NO auto-sync (no patch dispatch
follows: the report feeds the onboard backlog).
Target: full project at <PROJECT_ROOT>.
Scope:
1. README drift (build/test commands, install steps, usage examples vs actual code)
@@ -647,6 +652,7 @@ Si le skill ne supporte pas `--output`, capturer la sortie et écrire à la main
```
Agent(
subagent_type="general-purpose",
model="opus",
description="Onboard — static design review fallback",
prompt="""
AUDIT-ONLY mode — NO edits. Static design review du code UI.
@@ -690,6 +696,7 @@ Puis parser le JSON Lighthouse (scores perf/a11y/bp/seo/pwa + top opportunities)
```
Agent(
subagent_type="general-purpose",
model="opus",
description="Onboard — static perf audit",
prompt="""
AUDIT-ONLY mode — NO edits.
@@ -732,6 +739,7 @@ Parser axe-core résultats (violations, incomplete, inapplicable, passes) → `.
```
Agent(
subagent_type="general-purpose",
model="opus",
description="Onboard — static a11y audit",
prompt="""
AUDIT-ONLY mode — NO edits.
@@ -777,6 +785,7 @@ Spawn un subagent synthétiseur (isolé, chargé uniquement du contenu de `.onbo
```
Agent(
subagent_type="general-purpose",
model="opus",
description="Onboard — synthèse vers .claude/audits/",
prompt="""
Lire tous les fichiers de <PROJECT_ROOT>/.onboard-audit/ :
+10 -4
View File
@@ -2,13 +2,19 @@
name: plugin-check
description: 'Audit active plugins vs project needs. Read-only advisory recommending enable/disable. Triggers: "plugin-check", "quels plugins".'
argument-hint: '[ex: "React + FastAPI" or "Rust CLI, no frontend"]'
allowed-tools: Read, Bash, Glob, Grep
allowed-tools: Read, Bash, Glob, Grep, Agent
---
Load and follow strictly: `$HOME/.claude/agents/plugin-advisor.md`.
Run `$HOME/.claude/lib/plugin-gate.md` on the context below — dispatch
plugin-probe (sonnet) → validation checkpoint → dispatch plugin-advisor
(opus) → present the PLUGIN CHECK block (BDR-077: detection and reasoning
dispatched, gates in this loop).
Analyze active plugins + context below, produce PLUGIN ADVISOR REPORT.
/plugin-check is READ-ONLY advisory: SKIP the gate's step 5 (apply) — show
the advisor's exact toggle commands for the user instead. Never write; user
toggles via `claude plugin enable/disable`.
If `$HOME/.claude/agents/plugin-advisor.md` unreachable: emit `Plugin advisor agent missing.` and STOP. Never write — user toggles via `claude plugin enable/disable`.
If `$HOME/.claude/lib/plugin-gate.md` unreachable: emit `Plugin gate include
missing.` and STOP.
$ARGUMENTS
+80 -21
View File
@@ -302,14 +302,31 @@ still carries this rule for its applier:
If `Edit` is insufficient (full-template refactor), the item is escalated
as a cross-agent note → §11 user action instead.
## STEP 1 — Spawn both agents IN PARALLEL
## STEP 1 — Run both domain pipelines (3 phases; domains parallel per phase)
Issue both `Agent` tool calls **in the same message** (parallel tool
calls). The harness runs them concurrently.
BDR-077: each domain runs collect (sonnet) → judge (opus pin) → template
(sonnet), the two domains IN PARALLEL at every phase (both `Agent` calls
in the same message). Mint run ids first: `RUNID_SEO=$(date +%s)-seo`,
`RUNID_GEO=$(date +%s)-geo`. The CONTEXT payloads below are the SHARED
CONTEXT of each domain — pass them VERBATIM to every phase dispatch of
that domain (LRN-126). Clean both `.audit/*-signals-*.md` files after
STEP 2.
**DISPATCHER ERROR CONTRACT (fail-closed at the pipeline, not just the
judge):** a `SEO JUDGE — VERDICT: ERROR(…)` / `GEO JUDGE — VERDICT:
ERROR(…)`, a mute judge, or a BLOCKED collect → STOP that domain: NO
template dispatch, NO L1 apply for it. Surface the error verbatim, retry
ONCE with a fresh collect+judge for that domain; a 2nd failure →
escalate to the human. A mute or ERROR judge is NEVER carried into
templating.
**PHASE A — collect (both domains, one message):**
```
Agent(subagent_type="seo-analyzer")
Agent(subagent_type="seo-analyzer", model="sonnet")
prompt: """
MODE: collect
RUNID: <RUNID_SEO>
Dispatched from /seo. Context:
AUDIT DEPTH: <LOCAL|FULL>
@@ -379,18 +396,15 @@ SHARED-FILE EDIT DISCIPLINE (carried into each bundle item):
legal pages, new city/service pages.
- If full-template refactor is needed, emit as a cross-agent note → §11.
Execute your agent spec at ~/.claude/agents/seo-analyzer.md starting
at STEP 2 (skip STEP 0 and STEP 1 — context is provided above).
At STEP 13, emit the STRUCTURED ENVELOPE for merging (not a standalone
SEO.md), INCLUDING the `## FIX BUNDLE` section terminated by the verbatim
`READY TO APPLY — awaiting dispatcher confirmation` sentinel. Do NOT apply
any fix, do NOT dispatch any sub-agent, do NOT write SEO.md — /seo applies
your bundle in STEP 1.5 and merges the reports.
Execute MODE: collect per your spec — STEP 2-5 only (context above
replaces STEP 0-1). Write the signals file + COLLECTION COMPLETE
sentinel, emit the COLLECT REPORT, stop. No scoring, no bundle.
"""
Agent(subagent_type="geo-analyzer")
Agent(subagent_type="geo-analyzer", model="sonnet")
prompt: """
MODE: collect
RUNID: <RUNID_GEO>
Dispatched from /seo. Context:
AUDIT DEPTH: <LOCAL|FULL>
@@ -436,17 +450,62 @@ SHARED-FILE EDIT DISCIPLINE (carried into each bundle item):
llms-full.txt.
- If full-template refactor is needed, emit as a cross-agent note → §11.
Execute your agent spec at ~/.claude/agents/geo-analyzer.md starting
at STEP 2 (skip STEP 0 and STEP 1 — context is provided above).
At STEP 14, emit the STRUCTURED ENVELOPE for merging (not a standalone
GEO.md), INCLUDING the `## FIX BUNDLE` section terminated by the verbatim
`READY TO APPLY — awaiting dispatcher confirmation` sentinel. Do NOT apply
any fix, do NOT dispatch any sub-agent, do NOT write GEO.md/SEO.md — /seo
applies your bundle in STEP 1.5 and merges the reports.
Execute MODE: collect per your spec — STEP 2-5 only (context above
replaces STEP 0-1). Write the signals file + COLLECTION COMPLETE
sentinel, emit the COLLECT REPORT, stop. No scoring, no bundle.
"""
```
**PHASE B — judge (both domains, one message, AFTER both COLLECT REPORTs
are DONE):** no `model=` override — the opus frontmatter pins apply.
```
Agent(subagent_type="seo-analyzer")
prompt: "MODE: judge
RUNID: <RUNID_SEO>
<the seo SHARED CONTEXT verbatim>
Load .audit/seo-signals-<RUNID_SEO>.md (fail closed per your spec), run
STEP 6-11, report scoring + findings + action plan + triage batches."
Agent(subagent_type="geo-analyzer")
prompt: "MODE: judge
RUNID: <RUNID_GEO>
<the geo SHARED CONTEXT verbatim>
Load .audit/geo-signals-<RUNID_GEO>.md (fail closed per your spec), run
STEP 6-12, report scoring + findings + action plan + triage batches."
```
Apply the DISPATCHER ERROR CONTRACT above on each returned verdict.
**PHASE C — template (both domains, one message, only for domains whose
judge is DONE):**
```
Agent(subagent_type="seo-analyzer", model="sonnet")
prompt: "MODE: template
<the seo SHARED CONTEXT verbatim>
JUDGE REPORT (verbatim, ground truth — never re-derive a score):
<the seo judge report>
Run STEP 12-14: emit the STRUCTURED ENVELOPE for merging (not a
standalone SEO.md), INCLUDING the `## FIX BUNDLE` section terminated by
the verbatim `READY TO APPLY — awaiting dispatcher confirmation`
sentinel. Do NOT apply any fix, do NOT dispatch any sub-agent, do NOT
write SEO.md — /seo applies your bundle in STEP 1.5 and merges the
reports."
Agent(subagent_type="geo-analyzer", model="sonnet")
prompt: "MODE: template
<the geo SHARED CONTEXT verbatim>
JUDGE REPORT (verbatim, ground truth — never re-derive a score):
<the geo judge report>
Run STEP 13-15: emit the STRUCTURED ENVELOPE for merging (not a
standalone GEO.md), INCLUDING the `## FIX BUNDLE` section terminated by
the verbatim `READY TO APPLY — awaiting dispatcher confirmation`
sentinel. Do NOT apply any fix, do NOT dispatch any sub-agent, do NOT
write GEO.md/SEO.md — /seo applies your bundle in STEP 1.5 and merges
the reports."
```
## STEP 1b — CHALLENGE THE FIX BUNDLE (advisory, before apply)
Both envelopes now carry a `## FIX BUNDLE` — worth attacking before any edit lands.
**Skip if intervention mode = conservative** (nothing is applied). Else persist both
+15 -5
View File
@@ -20,7 +20,8 @@ $ARGUMENTS
---
## STEP 0 — PLUGIN CHECK + AUTO-ACTIVATE
Load `$HOME/.claude/agents/plugin-advisor.md`. Feed request.
Run `$HOME/.claude/lib/plugin-gate.md`. Feed request (dispatch plugin-probe →
checkpoint → dispatch plugin-advisor; gates stay in this loop — BDR-077).
- ACTION REQUIRED → show RECOMMENDATIONS block, offer: A) fix plugins B) type "force". STOP.
- PROPOSED CHANGES exist → show list, ask "Apply? (yes / no / customize)". Apply on confirm.
- OK → `✅ Plugin check passed — [active plugins] — complexity: <score>%`, continue.
@@ -51,7 +52,8 @@ ls .gsd/ROADMAP.md 2>/dev/null | head -1
STOP.
## STEP 0c — CTX7 CACHE CHECK (if fast-libs in project)
Check if the project uses fast-evolving libs (scan `package.json` for next, react, prisma, supabase, drizzle, expo):
Check if the project uses fast-moving libs — single source of truth:
`bash ~/.claude/lib/fast-libs.sh detect .` (exit 1 = none; BDR-078):
1. If `.ctx7-cache/` exists with recent files (<7 days old) → print `📚 ctx7 cache found: <libs>` and continue.
2. If `.ctx7-cache/` missing or stale AND `ctx7` is installed AND fast-libs detected:
```bash
@@ -222,7 +224,10 @@ conformity + security vs. craft/design) — both run, neither subsumes the
other ([[LRN-095]]).
## STEP 6 — CODE REVIEW
Invoke `superpowers:requesting-code-review`. Fix all CRITICAL before proceeding.
Invoke `superpowers:requesting-code-review`. **Model routing (BDR-077):** the
review subagent it dispatches MUST carry `model: "opus"` in the Agent call —
craft review is dispatched judgment, never inherited from the session. Fix
all CRITICAL before proceeding.
## STEP 7 — CAPITALIZE (memory registries)
Feature shipped implies at least one design decision worth capturing. Run this BEFORE STEP 9 FINISH — the implementation commits (STEP 4) already exist, so the entries' hash references are valid, and the memory commit lands on the branch that FINISH integrates (otherwise it strands outside the PR):
@@ -264,8 +269,13 @@ Run BEFORE STEP 9 FINISH. doc-syncer PATCHES public docs but does NOT commit the
uncommitted (or committed after) never reaches the merge/PR. Same PR-stranding class as the
STEP 7 capitalize fix (BDR-034).
Load `$HOME/.claude/agents/doc-syncer.md`. Execute in automatic mode:
`auto-mode scope: <list of files modified during this session>`
Dispatch the doc pipeline (BDR-077 — audit judgment on opus, patch on the
sonnet pin, gate HERE): `Agent(subagent_type="doc-syncer", model="opus")` —
`MODE: audit` + `auto-mode scope: <list of files modified during this
session>`. NONE → done; `[MINOR]` PATCH PLAN → re-dispatch
`Agent(subagent_type="doc-syncer")` with `MODE: patch` + the plan verbatim
(SHAPE ESCALATION comes back here, gated); SIGNIFICANT → gate here, then
`MODE: patch` with the approved subset.
**Then commit the docs** — follow `$HOME/.claude/lib/doc-commit.md`: it surgically commits
ONLY the files doc-syncer patched (its `PATCHED_FILES` output, one path per line → one argv
+3 -3
View File
@@ -111,9 +111,9 @@ honestly in the summary. Never loop past 3.
### Phase B — CLEAN
1. Dispatch a read-only cleanup audit (analyzer or general-purpose —
inherits the big session model; NOT the sonnet code-cleaner, which is
now a fix executor): dead code, unused imports/exports,
1. Dispatch a read-only cleanup audit (analyzer — opus-pinned, BDR-076 —
or general-purpose with `model="opus"`; NOT the sonnet code-cleaner,
which is now a fix executor): dead code, unused imports/exports,
commented-out blocks, stale flags, norm violations. Findings as
`id | file:line | finding | proposed fix`.
2. Apply **behavior-preserving** fixes only. A finding that would change
+1 -1
View File
@@ -1 +1 @@
1.1.0
1.2.0