agentm model effort routing - alexherrero/agentm GitHub Wiki
Note
LAUNCHED (lifted 2026-06-24, AG Phase 3; originally approved 2026-06-23) Β· locked 2026-06-28 (final AG design sweep). child-design β model + effort routing (automatically binding a model + reasoning-effort tier to each persona/role, so the right model runs each job without a per-session /model). A cross-cutting design, agentm-anchored. Points up at the agentm HLD.
Bind a model + reasoning-effort tier to each persona, and apply it automatically when that persona is adopted. Research then runs on the strongest model at the deepest setting, a long build stretch runs cheap, and nobody hand-sets /model per session. It is the concrete realization of foundation principle P9 ("match the model to the work") and of the efficient opinion's named model-routing lever. It is not a plugin: it is a policy (agentm), a per-persona binding (the persona manifest), and an enforcement surface (crickets agent-defs + the host).
Routing collapses two dimensions β model strength Γ reasoning effort β into one ordered tier scale, because in practice they co-vary (harder work wants a stronger model and more thinking). A persona declares a tier; adoption applies it. Frontier reasoning concentrates into bounded planning/verdict sessions while execution runs cheap everywhere else; the tier scale routes both sides of that split.
| Tier | The work it fits | Effort |
|---|---|---|
| T4 Β· Deep | research Β· adversarial audit Β· the hardest reasoning |
max + orchestration |
| T3 Β· Architect | cross-system design Β· roadmap Β· priority / board calls | max |
| T2 Β· Author | planning Β· PM Β· design authoring Β· holding the technical bar | high |
| T1 Β· Execute | long autonomous build stretches | medium |
| T0 Β· Mechanical | rote edits Β· log-scraping Β· deterministic passes | low |
Concrete model ids per tier β Claude and Gemini/Antigravity alike β live in token-audit's versioned routing table, the single home, refreshed by content-refresh in step with pricing.py. This chart states the portable tier + effort structure only; it does not need an edit when a model is renamed or replaced. The Claude-side table is the one built first β Gemini/Antigravity rows lag until that side of the portfolio needs its own consumption path (named honestly, not claimed as symmetric on day one). The effort ladder is low Β· medium Β· high Β· max; ultracode is the Claude-Code top-tier orchestration mode, not a fifth effort level.
T0/T1 rows carry the advisor rider (see Escalation below): opusplan stays T1's default pending session-cost data β the flip to a cheap main loop + advisor is that capture's first named consumer, not a decision made here.
| Persona | Tier | Note |
|---|---|---|
| Researcher Β· Reviewer (audit) | T4 | the hardest reasoning + adversarial breadth |
| Architect Β· Planner (roadmap mode) Β· Troubleshooter | T3 | cross-system + priority calls |
| Designer Β· Tech-Lead Β· Planner (planning/PM mode) | T2 | authoring + the technical bar |
| Engineer / Worker | T1 | the long build stretch (opusplan) |
| Operator Β· Maintainer Β· Memory | T0βT1 | read/report + mechanical repair |
A persona's tier is its default; a mode-dependent persona escalates one tier for a genuinely harder sub-task (e.g. Planner β T3 for a roadmap call). The escalation is bounded by the persona's declared ceiling.
T2 Β· Author is not one model: the work-type table (token-audit) splits it by shape β roadmap/architecture calls route to Opus 4.8 at high effort, transcription-shaped authoring (staging a plan whose reasoning is already settled elsewhere) routes to Sonnet 5 at high effort. The personaβtier map above states the tier; the work-type table states which of T2's shapes applies.
The tier scale above states the portable policy; this table is the empirical layer on top of it β session-classes the front-loaded AG + Autonomy era actually ran, recalibrated against what happened across five waves plus the whole arc. It governs session-class tier boundaries, not the concrete per-work-type model ids (those stay in token-audit's routing table, unchanged by this amendment).
| Work class | Tier | Evidence |
|---|---|---|
| Scope-lock re-audit execution (apply an existing decision table) | Sonnet, permanent | flawless table application, correct parks (v6-index task 1) |
| Plan-locked builds | opusplan (Sonnet exec) β unchanged | 5 waves + arc, one environmental escalation |
| Acceptance / conformance passes | Sonnet medium β confirmed | AA4 found and fixed two real fail-opens |
| Design landing, operator-interactive | Sonnet high β confirmed | operator-in-loop caught what the memo missed |
| Ratification walkthroughs | Sonnet (down from Opus) | the judgment in the room is the operator's; the model presents pre-rendered recommendations |
| Rendering new decision tables / residual-open-question verdicts | frontier β retained, narrowed | earns its keep on genuine open questions; restating an existing table doesn't |
| Calibration / model-bump re-audit | frontier, cadence-bound to model bumps | this recalibration itself |
| Risk-acceptance, economics, doctrine | operator-owned β no model tier; every tier routes it up | the governor-enforcement overturn (AA2): a frontier memo optimized against a risk class the billing model had already retired β the operator's call, not a tier failure |
| All tiers, standing | ESCALATE-and-park; evidence blockers park, never simulate | one real escalation in five waves + the Autonomy arc, correctly parked and resolved |
P9 + the efficient opinion set the policy; the personas declare tiers against the scale; enforcement renders a tier into a real model+effort per host and surface; token-audit's cost trend tunes the scale and content-refresh keeps its model strings current.
The scale is the canonical artifact: each tier is a (model-class, effort) bundle named by intent. It realizes the efficient opinion's model-routing lever β efficient is "cheap as the job allows, above the quality floor," and the scale is how that judgment becomes a concrete pick. It implements foundation P9. The scale lives here so it is defined once; personas, the opinion, and the enforcement surface all reference it rather than restating model names.
The scale currently draws on five pinned model ids (pricing.py, the ground truth): claude-opus-4-8, claude-sonnet-5 (current generation, introductory pricing through 2026-08-31), claude-sonnet-4-6 (prior generation β re-pinned off the three agent-defs that cited it as of the Wave D personas build, 2026-07-06; see Amendment log), claude-haiku-4-5, and claude-fable-5. Fable is real and pinned, but at roughly 2Γ Opus's per-MTok rate it is the single most expensive row token-audit's table carries, and no work-type resolves to it today β the standing operator convention keeps it unused, and the Mythos incident (112 sub-agents silently inheriting it) is the concrete reason why: an unrouted, expensive model is exactly what a silent inheritance defaults to if nothing positively identifies the work first.
That positive identification is the classifier (classify_work_type, hosted in token-audit alongside its table): given a dispatch or a staged plan, it resolves to a work-type key β from a persona's own declared tier, from an ad-hoc role-name match, or, failing both, an explicit UNCLASSIFIED-DEFAULT rather than a silent guess. The tier scale above is the policy the classifier's output is checked against; the classifier is how "which tier does this dispatch belong to" stops being answered ad hoc, in-prompt, per session.
The persona manifest gains a tier: field (and, where a persona spans modes, a tier-ceiling: for bounded escalation). This is the net-new axis: today the manifest declares stance Β· enhances: Β· requires: Β· opinions Β· modes Β· triggers, and carries no model or effort at all. Adding tier: makes "which model this stance runs on" a declared, validated property (extending check-personas.py), not an operator habit. The persona roster gains the tier column shown above.
A tier becomes a real model+effort differently depending on how the persona is running:
-
Spawned sub-agent personas β automatic, confirmed live. The agent-def carries
model:(and the neweffort:) frontmatter as a fallback default; the Agent tool's per-invocationmodelparam (enumsonnet/opus/haiku/fable) overrides it and is the real, host-documented lever β confirmed live in P12 (PLAN-efficiency-dispatchTask 8): anExploredispatch passedmodel="sonnet"self-reported backclaude-sonnet-5. Per-dispatch effort stays unbound: the Agent tool has no per-invocation effort param, and whether agent-defeffort:frontmatter itself binds is unverified across a session boundary β Task 2b's live spike hit an unrelated blocker (a new agent-def dropped into.claude/agents/isn't hot-reloaded mid-session, so the spike couldn't complete without ending the session). Re-audit trigger: re-run the agent-defeffort:spike in a fresh session β if it binds, the roster gains a real effort axis. -
Phase-command turns β advisory only, via the prose nudge β command frontmatter is decorative (retired 2026-07-04). P12 Task 0's live spike found
model:/effort:frontmatter on akind: commandskill/command has no observable effect on the turn's model: three throwaway scratch commands pinned toclaude-opus-4-8/opusplan/claude-sonnet-5all reported back the session's own baseline model, unchanged. A command injects text into the turn already running at whatever model the client picked at turn start β it is not a new dispatch the way the Agent tool is. The mechanism actually doing work is the prose nudge (> **Recommended model for this phase:**) already carried alongside the frontmatter inwork.md/plan.md/etc. -
Non-command turns and cross-turn persistence β advisory. Same nudge, same limit β free-form conversation turns and anything that must persist across turns surface the tier as a nudge ("recommended: T2 Β· Author β Opus high;
/modelto override") rather than an enforced switch, since the host has no lever to bind a model beyond a single dispatched sub-agent call. -
Build default β
opusplan, session-level only. The globalopusplanalias (Opus plans, Sonnet executes) is the host-level realization of T1 Β· Execute for build sessions β a built-in two-tier split that covers the worker's plan/execute rhythm without per-step selection. It is never a legal value for the Agent tool's per-invocationmodelparam and has no meaning for a single dispatched turn; the single-implementer invariant means it's never needed on the dispatch path.
Enforcement above routes downward β matching the model to the work at adoption or dispatch. The reverse direction, a cheap session hitting work above its tier, has three answers rather than a self-switch (the host permits neither a hook nor a running turn to change its own model):
-
The advisor rider. T0/T1 sessions set
advisorModelso a stronger model is consultable mid-task without switching the session's own model β config-only, no build. Anthropic-API-only; pinned to Opus 4.8 for now (Fable-as-advisor is version-gated to 2.1.170+, and the advisor must be at least as strong as the main session). -
The
/worktripwire. The same verification gate failing three consecutive attempts on one task emits a handoff-pack escalation entry (packed context + recommended tier), announces loudly, and stops at the safety gate β it never switches the model itself, because it can't. This is insurance for unattended sessions rather than a claimed workload: the failure mode it guards is a cheap model grinding a failing gate, with test-weakening as the worst exit. -
The budgeted-oracle primitive, held behind evidence. A budgeted frontier-tier subagent dispatched only for bounded hard-reasoning steps exists host-natively via Workflow's per-call
model/effortplus its tokenbudgetβ named here as the reach-for shape, not built now. Its trigger is the first tier-attributable correction observed in a cheap session; until then, building it would duplicate the advisor +opusplanagainst no observed demand, on a convention-grade budget the Mythos incident already showed to be insufficient.
The tier is the portable unit; each host renders it through the chart. Claude Code renders via model: + effort + (at T4) ultracode; Antigravity/Gemini render via the Pro/Flash classes + a thinking budget. Where a host can't honor a dimension (e.g. an effort field it doesn't read), the tier degrades to the nearest model-only pick and the advisory nudge carries the rest β the same graceful-skip posture the rest of the portfolio uses.
token-audit is measurement-only and one-way: its designed auto-capture (a per-model session-cost record reviewed in the dreaming pass) surfaces when a persona is running hotter than its tier warrants β the longitudinal signal that tunes the scale and the personaβtier map over time. token-audit's newly designed routing-conformance report reads its own hosted table from the other side β grading model-used vs. work-type after the fact β but that is reporting, not routing: routing decides, token-audit only ever measures and reports. Routing decides; token-audit never picks a model.
-
composed by personas β each persona declares a
tier:; this design owns the scale the field references. -
realizes the
efficientopinion's model-routing lever and implements foundation P9 (agentm foundations HLD) β the policy altitude. -
enforced through development-lifecycle β its agent-defs carry the
model:+effort:frontmatter as a fallback default, with the Agent tool's per-invocationmodelparam the confirmed-live override; its phase commands carry the prose nudge for the turn they run (command frontmatter itself is decorative, not enforced β P12 Task 0); (designed) its dispatch points additionally read token-audit's versioned routing table at dispatch time. The as-built precedent is that plugin's phase-aware-model-routing. - fed by token-audit β the cost trend that tunes the scale (one-way), and (designed) now hosts the versioned table this chart points to for concrete model ids. The policy β the tier + effort structure β stays here; the refreshable ground truth of "which real model" moves there, colocated with the price data it must agree with.
-
kept current by
content-refreshβ a model release re-pins token-audit's routing-table id strings + the Gemini column (mechanical), while a genuinely new model that needs a tier placement surfaces for operator review (judgment-bound). The weekly CI model-drift detector is what catches the release and opens thecontent-refreshissue. This is the standing answer to the mapping decaying on model releases. -
host-applied β Claude Code (
model:/ effort /opusplan/ultracode) and Antigravity/Gemini (the equivalents column). - Points up at the agentm HLD; the requires/enhances mechanics are in crickets-composition.
-
Generalize the as-built routing β crickets phase-aware-model-routing binds
model:to three roles today; lift it to the full persona roster and add the effort axis (net-new). The named model strings move behind the tier scale rather than being pinned per-command. -
Add the manifest field β
tier:(+tier-ceiling:) to the persona manifest schema +check-personas.py; add the roster column. ([PENDING-IMPL].) -
Move concrete model ids to token-audit's versioned table (this amendment, designed, not built) β the chart above sheds its Claude Code / Gemini columns; token-audit hosts the work-type-keyed table those columns become.
PLAN-efficiency-automation(crickets-side) stages the build of the table + its two consumers. -
Point the touched designs here β short pointer amendments in personas (the
tier:axis) and theefficientopinion (its model-routing lever specified here). Per the AG track these are living-design amendments, not a new ADR.
-
The whole thing is designed, not built (
[PENDING-IMPL]) β only the model-only, three-role as-built slice exists in crickets; the effort axis, the manifest field, the roster-wide binding, and the activation that reads it are greenfield (the persona "activation plumbing" is itself the unbuilt core). -
In-session enforcement is narrower than earlier believed β command frontmatter is decorative, not enforced (retired 2026-07-04). P12 Task 0's live spike found
model:/effort:frontmatter on akind: commandskill/command has no observable effect on the turn's model β a command injects text into the session's already-running turn, it doesn't open a new dispatch. The one confirmed-live enforcement mechanism is the Agent tool's per-invocationmodelparam on a genuine sub-agent dispatch (Task 8:Exploredispatched withmodel="sonnet"self-reportedclaude-sonnet-5). Phase-command turns and everything else stay advisory-only via the prose nudge, unchanged from the original design intent. Re-audit trigger: a future CLI version demonstrably honoring command-level frontmatter. -
The Agent tool has no per-invocation
effort. Onlymodelcan be passed per dispatch; whether agent-defeffort:frontmatter itself binds is unverified across a session boundary β P12 Task 2b's live spike couldn't complete (a new agent-def isn't hot-reloaded mid-session) β so effort stays out of this design's reachable dispatch-time mechanism until a fresh-session re-spike confirms or denies the frontmatter fallback. -
Version-gate hazards β the installed CLI (2.1.112) trails the documented version (2.1.201): Explore inherits the session model starting at 2.1.198 (the cheap-floor-Explore assumption silently inverts on upgrade β the announcement contract must cover built-in-agent inheritance, not just explicit dispatches). Confirmed live below that threshold (P12 Task 8): a model-less
Exploredispatch self-reportedclaude-haiku-4-5-20251001, not the session's ownclaude-opus-4-8β Explore carries its own fixed default, it does not inherit. TheINHERITEDannouncement label conservatively covers both "agent's own default" and "true inheritance," since the dispatch site can't distinguish them without introspecting the target agent-def; re-audit once the installed CLI reaches β₯2.1.198. Fable-as-advisor is gated to 2.1.170+. - Effort-field host support varies β Claude Code's effort/ultracode and Gemini's thinking budget are not the same control; the tier degrades gracefully where a dimension isn't honored.
-
Hosting the model-id table in token-audit (not here) trades a policy/data split for a single source of truth. An operator reading this chart sees the tier structure only, not which model is actually running for a work-type; they must follow the pointer to token-audit. The alternative β keep ids in this chart β was rejected because it duplicates
pricing.py's spelling responsibility, the exact drift the one-pinned-source pattern exists to prevent. -
Quality-shaped escalation has no deterministic trigger. The Escalation section's
/worktripwire (above) catches a session stuck on a failing gate β a counter on verification hooks, mechanical. It does not catch a session that is confidently wrong: cheap-tier output that passes every gate but is substantively wrong because the work genuinely needed a stronger model's judgment. There is no deterministic signal for "this session is out of its depth" the way a failing test signals "this session is stuck." The residual coverage is judgment-triggered, not mechanism-triggered: the advisor rider, if the session recognizes its own uncertainty and calls it, or a human noticing later (at/review, or reading the output). Named honestly rather than implying the Escalation section is a complete answer to "a cheap session hits work above its tier" β it fully answers the stuck sub-case; the quietly wrong sub-case stays advisor/human territory. -
The chart decays on model releases β now token-audit's table decays instead;
content-refreshcarries the re-pin as a named checklist item (mechanical re-pin auto-applied; a new-model tier placement surfaces for review), triggered by the weekly CI model-drift detector, and a model bump is also a P8 re-audit trigger. -
Re-audit triggers: add the
tier:manifest field + validator; generalize the agent-def routing + addeffort:; wire activation to apply the tier at adoption; wirecontent-refreshto re-pin token-audit's table; re-pin on every model release; confirm the personaβtier map against realsession-costtrends once token-audit's capture ships; Gemini/Antigravity rows land in token-audit's table when that side needs its own consumption path; a host ever exposes a self-assessed-uncertainty signal a quality-escalation trigger could key on.
-
As-built precedent: crickets
development-lifecyclephase-aware-model-routing βagents/worker.md,researcher.md,tech-lead.md(all threemodel: claude-sonnet-5as of 2026-07-06 β see Amendment log); the phase-command prose nudges (frontmatter itself is decorative β not enforced, P12 Task 0); global~/.claude/settings.jsonopusplan -
Principle + policy: agentm foundations HLD (P9 Β· match the model to the work) Β·
efficientopinion (the model-routing lever) -
Binding + enforcement + feed: personas (the
tier:axis) Β· development-lifecycle (agent-def frontmatter + the designed dispatch-time table read) Β· token-audit (the cost trend + the versioned routing table, single home of current model ids + the designed routing-conformance report) Β·content-refresh(table re-pin) - Up: agentm HLD Β· composition
2026-07-08 β AA5 work-class recalibration: added the evidence-based tier table for session classes; ratification walkthroughs move Opus β Sonnet; a new operator-owned, no-tier decision class is named. The AA re-entry retrospective (AA5-REENTRY-VERDICT.md Β§3, operator-ratified same day) graded five AG waves plus the whole Autonomy arc against the tier scale and found four permanent tier-downs plus one gap: scope-lock re-audit execution (applying an existing decision table) drops to Sonnet permanently β the v6-index session applied one flawlessly; acceptance/conformance passes and operator-interactive design landings both confirm at their existing Sonnet tiers rather than moving; ratification walkthroughs (the AA0 class) drop from Opus to Sonnet, since the judgment in the room at a ratification is the operator's, not the model's; rendering genuinely new decision tables or residual-open-question verdicts keeps the frontier tier but narrows to that case only β table-restating doesn't need it; and calibration / model-bump re-audits (this entry is one) are named as a frontier session-class, cadence-bound to model bumps. The new row is risk-acceptance / economics / doctrine, operator-owned with no model tier at all β every tier routes it up regardless of session class, evidenced by the AA2 governor-enforcement overturn: a frontier memo had specified spawn-denial and a kill path against a runaway-bill risk the subscription billing model had already retired, and the operator deleted it at review. ESCALATE-and-park is reaffirmed universal at every tier β it fired once in five waves plus the arc and was correct that once. Why a new table rather than editing the persona β tier map above: the persona map binds a role (Researcher, Worker, Planner) to a tier; this table calibrates session classes that cut across roles (a ratification walkthrough can happen inside any persona's session) β collapsing the two would blur what each is keyed on. Why not touch token-audit's routing_table.py: verified directly β that table binds concrete work-type rows to model ids, a different axis than the session-class boundaries this amendment governs; nothing in AA5 Β§3 changes a work-type row, so it's untouched. Why not edit personas or the efficient opinion: both already carry only generic pointers at this design's tier scale (T0β¦T4) and the tier: manifest axis, neither naming a specific work class this amendment recalibrates β no edit needed, checked directly rather than assumed. Re-audit trigger: the next model bump (per principles Β§6) β that is also when the next calibration-class frontier session runs.
2026-07-06 β Wave D re-audit: agent-def effort: frontmatter confirmed BINDS; the three-agent-def model-id drift already closed. The P12 Task 2b re-audit trigger fired at the start of PLAN-wave-d-personas's task 4, in a genuinely fresh session. The prior spike's blocker (a new agent-def dropped into .claude/agents/ isn't hot-reloaded mid-session) couldn't be safely reproduced this time either β no local .claude/agents/ existed in the worktree, and mutating the live shared plugin cache to force a hot-reload test would have been an invasive, out-of-scope action on shared infrastructure. Instead, the fresh session checked the primary source directly: Claude Code's own subagent documentation (https://code.claude.com/docs/en/sub-agents) now lists effort as a real, current, first-class frontmatter field β "Effort level when this subagent is active. Overrides the session effort level... Options: low, medium, high, xhigh, max" β carrying no min-version gate (unlike several neighboring rows), so it applies unconditionally on the installed CLI (2.1.193). The Agent tool's own per-invocation params still expose only model, no per-dispatch effort, so the binding is frontmatter-only β consistent with, not contradicting, model:'s existing dispatch-time-default behavior. Recorded: BINDS. Also confirmed, while re-checking this design's own "still name claude-sonnet-4-6" citation (line 66 as of the prior amendment): the three agent-defs (worker.md, researcher.md, tech-lead.md) already carry model: claude-sonnet-5 β the content-refresh gap this design flagged as "live, not hypothetical" had already closed by the time Wave D re-checked it; the citation is corrected to stop pointing at a stale gap. Why not treat the hot-reload blocker as still open: the fresh-session constraint was "test via a different, safe mechanism," not "force the identical mechanism through" β a primary-documentation check is a stronger, more current signal than an empirical mid-session mutation of shared plugin state would have been anyway, since the doc is the host's own contract for the field. Re-audit trigger: if a future safe, non-invasive empirical dispatch test (e.g. once a project-local .claude/agents/ exists that a session can populate without touching shared plugin cache) contradicts the documented behavior, reopen this call.
2026-07-04 β P12 live-spike correction: command frontmatter does not pin a turn's model; retire the "turn-scoped automatic" enforcement bullet. PLAN-efficiency-dispatch Task 0 spiked live (three throwaway scratch commands pinned model: claude-opus-4-8 / opusplan / claude-sonnet-5; all three reported back the session's own baseline model, unchanged) and found model:/effort: frontmatter on a kind: command skill/command has no observable effect β a command injects text into the turn already running, it does not open a new dispatch. This retracts the P14 verdict's "in-session enforcement is no longer advisory-only" upgrade (previous entry, below): that upgrade was inferred from the host's documented schema without a live spike against a real command dispatch, and the spike came back negative. What Task 8 confirmed live instead: the Agent tool's per-invocation model param (enum sonnet/opus/haiku/fable) IS a real, honored override on a genuine sub-agent dispatch β an Explore call passed model="sonnet" self-reported claude-sonnet-5 back. opusplan is confirmed session-level only β never a legal per-dispatch value, and moot in practice since the single-implementer invariant never routes /work's own implementer through this path. Per-dispatch effort stays unbound: Task 2b's live spike to test whether agent-def effort: frontmatter binds hit an orthogonal blocker (a new agent-def isn't hot-reloaded mid-session), so cross-session support is unverified, not negative β a narrower, honest gap than the frontmatter finding. Also folds in Task 8's Explore finding: below the installed CLI's 2.1.198 threshold, Explore carries its own fixed default (self-reported claude-haiku-4-5-20251001 on a model-less dispatch, not the session's claude-opus-4-8) rather than inheriting β the INHERITED announcement label conservatively covers both "agent's own default" and "true inheritance" since a dispatch site can't cheaply distinguish them. Why not leave the "turn-scoped automatic" bullet standing pending a re-spike: the P14 verdict's claim was already live-contradicted by the time this correction landed β leaving it in the design would misdirect the next reader into treating a decorative frontmatter field as a real lever. Why not also drop the effort-axis language entirely: Task 2b's finding is a blocked spike, not a negative one β the roster's model:-only-frontmatter posture stays provisional, not final, until the re-audit trigger below fires. Re-audit triggers: re-run the agent-def effort: spike in a fresh session (if it binds, the roster gains a real effort axis); a future CLI version demonstrably honors command-level model:/effort: frontmatter; installed CLI reaches β₯2.1.198 (Explore begins true session inheritance β sharpen the INHERITED vs. agent frontmatter distinction then).
2026-07-04 β P11 v2 pressure-test correction: model ids move to token-audit's versioned table; the chart keeps tiers + effort only; T2 splits by work-shape; the known models + the classifier named explicitly; the quality-escalation residual named honestly. The tier chart drops its concrete Claude-Code/Gemini model-id columns, keeping tier + effort as the portable policy; the concrete, refreshable mapping moves to token-audit's versioned table (its amendment, this same date). Seeds T2 Β· Author as two work-shapes rather than one model: roadmap/architecture calls β Opus 4.8 high; transcription-shaped authoring β Sonnet 5 high (Phase-R evidence: the roadmap session ran Opus, the tech-lead staging sessions ran Sonnet 5 high, wiki/mechanical-plus work ran Sonnet 5 medium β the correction audit attributes zero corrections to any of these picks). Names the five known model ids explicitly, including claude-fable-5 (real, pinned, ~2Γ Opus's rate, deliberately unrouted) and the classify_work_type classifier that resolves a dispatch to a table row. Adds an honest residual to Risks: the /work tripwire (P14c) is a complete answer to a stuck session, not to a confidently wrong one β quality-shaped escalation has no deterministic trigger; advisor/human judgment is the only coverage for it. Why not keep model ids in this chart: they change on a different cadence than the tier policy, and duplicate pricing.py's spelling responsibility β see token-audit's amendment for the fuller reasoning. Why not build a quality-escalation trigger now: no deterministic signal exists for "this output is wrong but the gates are green" β inventing one without a concrete mechanism would just be a false confidence badge; naming the gap is more honest than papering it. Why name Fable and the classifier here rather than leaving them implicit: an unrouted, premium-priced model is exactly what a silent inheritance defaults to, and the Mythos incident is the record of that; naming Fable's rate and its unrouted status turns "wait, what's that model" into instant pattern-recognition the moment an INHERITED announcement shows it, and naming the classifier makes explicit that a tier is resolved by a deterministic function reading a declared or matched key, never by an LLM guessing what kind of work this is. Re-audit triggers: Gemini/Antigravity rows land in token-audit's table when that side needs its own consumption path; a host ever exposes a "confidence" or self-assessed-uncertainty signal a quality-escalation trigger could key on; first tier-attributable correction in a cheap session (existing trigger, unchanged).
2026-07-04 β P14 routing-autonomy verdict: enforcement ceiling raised to the host's actual line; escalation designed in both directions (P14c, operator-approved). Three upgrades, one reaffirmation. (1) In-session enforcement is no longer advisory-only: the host documents model: + effort: frontmatter on skills/commands, applied turn-scoped β phase commands now carry their tier as frontmatter, and the nudge shrinks to non-command turns + cross-turn persistence; the old "a host can't force a slash-command's model" risk line is retired as stale. (2) Escalation gets a designed reverse path: the host advisor as the T0/T1 rider (config-only, advisor β₯ main β shaped for cheap main loops; Opus 4.8 until Fable-advisor's 2.1.170 gate clears), plus a deterministic /work tripwire (same verification gate failing 3 consecutive attempts β handoff-pack escalation entry + loud announce + safety-gate stop β never a self-switch, which the host forbids). (3) The protocol-level inversion Phase R actually ran is named as the architecture: frontier reasoning in bounded planning/verdict sessions, cheap execution, the tier scale routing both sides. Reaffirmed: the main session's model stays a human act at launch β the host's constraint line (hooks cannot set a model; a scheduled turn cannot self-fire /model; the advisor cannot be forced), not design timidity β and the single-implementer invariant is untouched. Why not the fuller-automation alternatives: launcher-level work-type detection re-derives what the chosen command/pack already declares and can misroute silently with no in-session correction channel; a custom budgeted frontier-oracle subagent duplicates advisor + opusplan against zero observed demand (Phase-R correction audit: model-capability class = 0 across P1βP7c) with only a convention-grade budget (the Mythos incident is the record of convention-grade controls failing); flipping T1 off opusplan to cheap-main+advisor is plausible but unquantified β named as session-cost capture's first consumer, not decided now. Re-audit triggers: first tier-attributable correction in a cheap session (revisit the oracle); the host ships per-invocation effort on the Agent tool, a session-persistent command pin, a forced/cappable advisor, or cron-level model pinning (raise the ceiling again); CLI upgrade past 2.1.170 / 2.1.198 (Fable-advisor unlocks; Explore begins inheriting the session model β announcement contract must already cover it); session-cost capture live (adjudicate the T1 flip).
2026-07-03 β dropped governs: (was personas/*.md, scripts/check-personas.py), area-only until the tier: axis has its own file (R0.10 / agentmDesigns#1 governs-overlap fix). This design and personas both stamped scripts/check-personas.py in governs:, so governs_resolver.py resolved the file as {"governed": false, "reason": "overlap"} β silently greenfield to grounding Hooks 1/2. check-personas.py validates the persona manifest as it stands today (requires β substrate, no-always-load) β none of that is the tier: axis this design adds; the file belongs to personas until a tier: validator exists as its own script. Rather than fight over the one file, this design drops governs: entirely and stays area-only (still reachable via area: agentm/model-effort-routing for area-taxonomy lookups) β the cross-cutting tier: axis has no code surface of its own yet; the [PENDING-IMPL] items in Risks are exactly that gap. Why not keep the glob and let personas drop instead: check-personas.py checks persona-manifest structure, not model/effort tiers β the file's real owner is the persona design, not this one. Re-audit trigger: when the tier: manifest field + its validator script ship (see Risks), add governs: [scripts/check-<tier-validator>.py] here.
2026-06-28 β lock-down sweep (operator review). Replaced the mermaid diagram with a hand-authored SVG (agentm-model-effort-routing.svg, house style, sized) β the first of the mermaidβSVG conversions. Reordered the amendment entries newest-first. Locked as a v5βv8 guidepost.
2026-06-28 β worker.md realigned to T1 (critique ruling 8). The crickets development-lifecycle worker agent-def moved model: claude-opus-4-8 β claude-sonnet-4-6 (the T1 executor; crickets development-lifecycle 0.27.0, CHANGELOG-recorded), resolving the W4 as-built/design contradiction β the design specified workerβT1 while the code pinned full Opus. The as-built-precedent reference above is updated to match. Re-audit: none β design + code now agree; the broader effort-axis + tier: wiring stays [PENDING-IMPL].
2026-06-23 β authored, reviewed, and finalized. Homed as its own cross-cutting design, agentm-anchored (not a plugin, not a single-doc amendment): the policy is the efficient opinion + foundation P9, the per-persona binding is a new tier: axis on the persona manifest, and enforcement spans crickets agent-defs + the host. Model + effort are normalized to a five-tier scale (T0 Mechanical β¦ T4 Deep) with Claude + Gemini equivalents β T4βT2 on Opus / Gemini 3 Pro, T1 Execute on opusplan / Gemini 3.5 Flash high, T0 Mechanical on Sonnet-Haiku / Gemini 3.5 Flash normal (operator-set; on Gemini the bottom two tiers are one Flash model at differing effort, no ProβFlash split) β plus a personaβtier map (research/auditβT4, roadmapβT3, planning/PMβT2, workerβT1).
The net-new pieces are all [PENDING-IMPL]: the effort axis (today's as-built crickets phase-aware-model-routing is model-only, three roles), the tier: manifest field + validator, roster-wide binding, and activation that applies the tier at adoption. token-audit feeds the tuning trend one-way; content-refresh carries the chart as a named refresh-checklist item β a model release auto-re-pins the version strings + Gemini column, while a genuinely new model's tier placement surfaces for review. Next (wiring): short pointer amendments into personas (the tier: axis) + the efficient opinion (the routing lever). Re-audit: add the tier: field + validator; generalize the agent-def routing + add effort:; wire activation + content-refresh; re-pin on every model release.