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.
278 lines
19 KiB
Markdown
278 lines
19 KiB
Markdown
# 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).
|