Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "model-routing",
"description": "Tiered model routing for token economy: the strongest model thinks, cheaper models grind. Ready-made subagents (sonnet scout, implementer and E2E runner, haiku surveyor, test-runner and verifier, opus reviewer) plus a routing skill and dispatch stats.",
"description": "Tiered model routing for token economy: the strongest model thinks, cheaper models grind. Ready-made subagents (sonnet scout, implementer, task-reviewer and E2E runner, haiku surveyor, test-runner and verifier, opus reviewer) plus a routing skill and dispatch stats.",
"version": "0.16.6",
"author": {
"name": "Artem Frolov"
Expand Down
22 changes: 14 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ reason written down in `evals/forced-dispatch-tier/NOTES.md`.)
| `agents/test-runner.md` | haiku | low | Run tests/builds/linters, report failures compactly. Never fixes anything. |
| `agents/e2e-runner.md` | sonnet | medium | Drive Playwright/E2E scenarios, interpret failures (product bug vs test bug vs flake). |
| `agents/implementer.md` | sonnet | medium | Implement one well-defined task from an approved plan. Verifies its own work. Dispatch with `model=opus` for multi-file/architectural/subtle work. |
| `agents/reviewer.md` | opus | high | Review a diff for correctness bugs, ranked by severity. |
| `agents/reviewer.md` | opus | high | Review a diff for correctness bugs, ranked by severity. Final/whole-branch, high-risk and pre-PR review. |
| `agents/task-reviewer.md` | sonnet | high | Per-task reviews and scoped re-reviews inside a plan loop (Superpowers SDD), following the caller's review template. Flags diffs that need `reviewer` instead. |
| `agents/verifier.md` | haiku | medium | Cheap gate on a subagent's diff: does it match the task (scope, completeness, obvious breakage)? Not a code review. |
| `skills/model-routing/` | - | - | The routing table and delegation rules Claude follows when deciding where work goes. |
| `hooks/routing-anchor.md` | - | - | Short routing anchor auto-injected at session start - zero config. |
Expand Down Expand Up @@ -199,6 +200,7 @@ flowchart LR
C["'Implement tasks 1-3 from the plan'"] --> IM["implementer<br/>sonnet / medium"]
D["'Refactor the payment pipeline'"] --> IMO["implementer<br/>model=opus / medium"]
E["'Review the diff'"] --> RV["reviewer<br/>opus / high"]
G["'Review Task 2' (plan loop)"] --> TRV["task-reviewer<br/>sonnet / high"]
F["'Design the architecture'"] --> MS["main session<br/>your strongest model"]
```

Expand Down Expand Up @@ -238,7 +240,7 @@ For local development: clone the repo and
- Continuing a stuck agent uses `SendMessage` when the harness provides
it; where it is absent the skill falls back to re-dispatching with the
packaged state. Neither path is a hard requirement.
- What "read-only" means here: scout, reviewer, verifier and test-runner
- What "read-only" means here: scout, reviewer, task-reviewer, verifier and test-runner
block the file-edit tools (`Edit`, `Write`, `NotebookEdit`) at the tool
level via `disallowedTools`. `Bash` (needed to run tests and inspect
repos) and MCP tools remain available and could in principle mutate
Expand Down Expand Up @@ -269,6 +271,7 @@ For local development: clone the repo and
| "Run the tests" | `test-runner` | haiku / low |
| "Implement tasks from the plan" | `implementer` | sonnet / medium (`model=opus` for complex work) |
| "Review the diff" | `reviewer` | opus / high |
| Per-task review in a plan loop | `task-reviewer` | sonnet / high |
| "Walk through the flow in the browser" | `e2e-runner` | sonnet / medium |

The main session spends tokens only on planning, decisions, final
Expand All @@ -284,9 +287,10 @@ Works with any plan-driven process (superpowers or similar):
2. Plan execution goes to `implementer` with a batch of related tasks
per dispatch (one agent per batch, not per task - every fresh agent
re-reads files from scratch).
3. Verification: `test-runner` after each batch, `reviewer` on the
completed chunk, and for high-risk diffs a final review in the main
session.
3. Verification: `test-runner` after each batch, `task-reviewer`
(sonnet) for the loop's per-task reviews and scoped re-reviews,
`reviewer` (opus) on the completed chunk or branch, and for high-risk
diffs a final review in the main session.

### "I don't want the expensive model"

Expand Down Expand Up @@ -316,7 +320,8 @@ let Claude route via the skill:
work goes out with `model=opus`.
- "Review the diff" - Claude dispatches `reviewer` (opus). For high-risk
diffs, ask for review in the main session instead - one expensive pass
is cheaper than a missed bug.
is cheaper than a missed bug. Per-task reviews inside a plan loop go to
`task-reviewer` (sonnet).
- "Walk through the checkout flow in the browser" - Claude dispatches
`e2e-runner` (sonnet).

Expand All @@ -339,8 +344,9 @@ earns its cost (the knobs themselves:
| --------- | ----- | ------ | -------------- | --------------- |
| Exploration (`scout`) | sonnet | low | Finding and tracing code is retrieval, not reasoning - a cheap tier reports as well as a costly one, and the file volume stays in the subagent regardless. | The work is mechanical lookup; extra thinking buys nothing. |
| Ordinary implementation (`implementer`) | sonnet | medium | Sonnet 5.5 pairs speed with intelligence at half the opus price ($2/$10 against $4/$20) - for work whose approach the plan already decided, the margin never changes the outcome. | The plan already decided the approach; the agent executes real logic, not design, and medium is where Sonnet 5.5's own guidance starts well-specified agentic coding. |
| Complex implementation (`implementer` `model=opus`) | opus | medium (pinned) | Multi-file or cross-layer changes, security/money/migrations/concurrency/public contracts, or a retry after a weak sonnet result - a wrong approach is expensive, and Opus 5.5 is stronger again at 20% less than Opus 5 ($4/$20, cache reads 60% less), so escalate when in doubt. This holds on every session model, Fable included: Opus 5.5 is cheaper than Fable 5.1 on every token type. (Ambiguous tasks are not an escalation case: implementer stops on ambiguity by contract - clarify first.) | The `model=opus` dispatch changes the model only - the Agent tool has no effort param, so the pinned medium stays; the escalation buys the tier, not extra thinking. |
| Complex implementation (`implementer` `model=opus`) | opus | medium (pinned) | Multi-file or cross-layer changes, security/money/migrations/concurrency/public contracts, or a retry after a weak sonnet result - a wrong approach is expensive, and Opus 5.5 is stronger again at 20% less than Opus 5 ($4/$20, cache reads 60% less). This holds on every session model, Fable included: Opus 5.5 is cheaper than Fable 5.1 on every token type. (Ambiguous tasks are not an escalation case: implementer stops on ambiguity by contract - clarify first.) | The `model=opus` dispatch changes the model only - the Agent tool has no effort param, so the pinned medium stays; the escalation buys the tier, not extra thinking. |
| Code review (`reviewer`) | opus | high | Review is an asymmetric bet - one pass guards against a bug that costs far more if it ships, so it is the one place to prefer the top tier by default. | High: subtle correctness bugs hide from shallow reading. The case for `medium` grew with Opus 5.5 - its `medium` matches or exceeds Opus 5 at `high` on coding and it thinks more per turn at a given level, so the same pin costs more - but that is vendor evidence, not this plugin's own review eval; the pin stays high until a medium-vs-high review run on Opus 5.5 is measured. |
| Per-task review in a plan loop (`task-reviewer`) | sonnet | high | Superpowers SDD scales the model of its per-task reviews and scoped re-reviews to the diff, with a mid-tier floor; a sonnet-pinned agent takes those seats instead of `reviewer` with `model=sonnet`, which undercuts its pin. Final, whole-branch, high-risk and pre-PR review stays on `reviewer`. | High: same correctness job as `reviewer`, on a smaller diff. |
| Tests / builds (`test-runner`) | haiku | low | Running a command and summarizing output is mechanical; the value is keeping raw logs out of the main context, not the model doing it. | Low: no reasoning, just report. |
| Diff sanity gate (`verifier`) | haiku | medium | Checking a diff matches its task (scope, completeness, obvious breakage) is a cheap spot-check, not a quality judgment. | Medium: completeness is the job, and at `low` Haiku 5.5 "is more likely to skip a search, stop early, or skip a check". |
| E2E / failure interpretation (`e2e-runner`) | sonnet | medium | Driving a browser and telling a product bug from a flake needs some judgment, but not top-tier reasoning. | Medium: real interpretation, clear method. |
Expand Down Expand Up @@ -442,7 +448,7 @@ step up on evidence.
| ------ | ------------ | ------------------------ |
| low | Most efficient: significant token savings with some capability reduction. On the Opus 5 generation low/medium punch well above their weight. | Pins: `scout`, `test-runner` (on the cloud platforms `haiku` is Haiku 4.5, which has no effort knob, so there the haiku pins only document intent). |
| medium | Balanced: real logic whose approach is already decided, at moderate savings. On Opus 5.5, Sonnet 5.5 and Haiku 5.5 this is the model's own default, so a pin at medium steps down only from a session running high or above. | Pins: `implementer`, `e2e-runner`, `surveyor`, `verifier`. Recommended session setting. |
| high | Full capability - Claude Code's per-model default except on Opus 5.5, Sonnet 5.5 and Haiku 5.5 (medium) and Opus 4.7 (xhigh). Complex reasoning, subtle debugging, high-risk review. | Pin: `reviewer`. Main-session planning and final review. |
| high | Full capability - Claude Code's per-model default except on Opus 5.5, Sonnet 5.5 and Haiku 5.5 (medium) and Opus 4.7 (xhigh). Complex reasoning, subtle debugging, high-risk review. | Pins: `reviewer`, `task-reviewer`. Main-session planning and final review. |
| xhigh | Extended capability for long-horizon agentic/coding runs (multi-hour, token budgets in the millions). | Session-level or Workflow `effort` opt only - never an agent pin. |
| max | Unconstrained token spend for frontier-grade problems; Anthropic notes diminishing returns and overthinking risk on routine work. | Not used by any pin - reach for it deliberately or not at all. |

Expand Down
32 changes: 32 additions & 0 deletions agents/task-reviewer.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
---
name: task-reviewer
description: Per-task reviews and scoped re-reviews inside a plan-driven loop such as Superpowers subagent-driven-development, and any review explicitly asked for at the sonnet tier. NOT for final or whole-branch review, security/money/migrations/concurrency/public-contract changes, or pre-PR review - those go to reviewer.
model: sonnet
effort: high
disallowedTools: Edit, Write, NotebookEdit
---

You review one task's changes, or one fix round, for defects.

The caller's prompt defines scope and output format - usually a review
template from the plan loop. Follow it exactly. When it gives no format,
use the reviewer agent's focus (correctness, regressions, security,
design, tests) and its report format: file:line, one-sentence defect,
concrete failure scenario, fix direction; end with safe to merge / needs
fixes / needs rework.

Rules:

- Escalate first: if the diff touches security, money, migrations,
concurrency or public contracts, or is too large to review well in one
pass, say so in the first line of the report so the caller can
re-dispatch `reviewer`. Then review what you can.
- Verify before reporting: for each suspected bug, trace the actual code
path that triggers it. Report only findings you can defend with a
concrete failure scenario.
- Review the whole diff before you report. Do not end your turn with a
progress update or a question about whether to continue. Stop early
only when nothing can move without the caller.
- Style nits only if the caller asks. Do not pad the report.
- Do not dispatch subagents.
- Never edit code. Review only.
1 change: 1 addition & 0 deletions hooks/dispatch-counter.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ const AGENT_PINS = {
"model-routing:verifier": { model: "haiku", effort: "medium" },
"model-routing:implementer": { model: "sonnet", effort: "medium" },
"model-routing:reviewer": { model: "opus", effort: "high" },
"model-routing:task-reviewer": { model: "sonnet", effort: "high" },
};
// Model pins for OTHER plugins' agents, curated by hand from their frontmatter
// the same way AGENT_PINS is - the difference is these files live outside this
Expand Down
4 changes: 2 additions & 2 deletions hooks/routing-anchor.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ MODEL ROUTING ACTIVE - expensive model thinks, cheap models grind. You cannot sw

- Main session: planning, specs, docs, architecture, small interactive edits. Trivial questions answerable from context or general knowledge: answer inline - a dispatch costs more than the answer.
- Exploration, by what has to come back: a judgement about what code does -> `scout`; a complete list or ordering verified by following the code -> `surveyor` (haiku); unverified candidate files -> built-in Explore with `model=haiku` (bare, it inherits the session model). With a code-graph MCP connected, query the graph first; scout verifies file:line.
- Approved plan/spec -> `implementer` (sonnet). Pass `model=opus` (Fable sessions too; the pinned medium effort stays) for multi-file/cross-layer work, security/money/migrations/concurrency/public contracts, or a retry after a weak sonnet result; when in doubt, opus. Ambiguous task or unclear root cause: clarify first (main session or scout) - implementer stops on ambiguity. No approved plan: have it return its PLAN and check it here before it writes code. Batch related tasks per agent.
- Review -> `reviewer`; high-risk or large diffs get final review in the main session. Batched implementer output you will not read in full -> `verifier`, never on the main session's own work. Tests/builds -> `test-runner`; E2E and failure interpretation -> `e2e-runner`.
- Approved plan/spec -> `implementer` (sonnet). Pass `model=opus` (Fable sessions too; the pinned medium effort stays) for multi-file/cross-layer work, security/money/migrations/concurrency/public contracts, or a retry after a weak sonnet result. Ambiguous task or unclear root cause: clarify first (main session or scout) - implementer stops on ambiguity. No approved plan: have it return its PLAN and check it here before it writes code. Batch related tasks per agent.
- Review -> `reviewer`; plan-loop per-task reviews and scoped re-reviews (Superpowers SDD) -> `task-reviewer` (sonnet); high-risk or large diffs get final review in the main session. Batched implementer output you will not read in full -> `verifier`, never on the main session's own work. Tests/builds -> `test-runner`; E2E and failure interpretation -> `e2e-runner`.
- Effort (low/medium/high/xhigh/max; Claude Code default medium on Opus 5.5, Sonnet 5.5 and Haiku 5.5, xhigh on Opus 4.7, high elsewhere): low mechanical, medium implementation, high architecture/debugging/review, xhigh/max only long-horizon or frontier work. On xhigh/max review only what the plan, the user or these rules ask - no self-started second round, no extra reviewer subagents. A dispatch carries no effort param: bundled agents pin theirs, Workflow `agent()` takes an `effort` opt.
- Stuck on the approach: the agent hands back; decide, then continue the same agent (SendMessage, else re-dispatch with its packaged state). Unfinished return with no blocker named: continue it the same way at the same tier. Failed or weak RESULT: fresh dispatch one step up (next tier via `model`, or higher Workflow `effort` when the miss is shallow thinking); a second failure comes to the main session. `stop_reason: "refusal"` is a classifier, not weakness: rephrase or drop, never re-dispatch a tier up.
- Pins: a pin above the session model gets capped at the session model via `model` - a bare dispatch runs the pin. Never push a dispatch below the lower of pin and session model; when a cheaper tier fits, pick an agent pinned for it. CLAUDE_CODE_SUBAGENT_MODEL_FORCE overrides `model` and pins; plain CLAUDE_CODE_SUBAGENT_MODEL only decides bare unpinned dispatches.
Expand Down
16 changes: 11 additions & 5 deletions skills/model-routing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,8 @@ carries no effort param:
| Complex implementation: multi-file refactor, subtle concurrency/security | subagent | `implementer` with `model=opus` | medium (pinned) |
| Trivial mechanical tasks: renames, boilerplate, mirrored constants | subagent | sonnet | low |
| Small interactive edits, quick fixes | main session | strongest | low |
| Code review of implemented work | subagent | `reviewer` (opus) | high |
| Per-task review and scoped re-review inside a plan loop (Superpowers SDD) | subagent | `task-reviewer` (sonnet) | high |
| Final/whole-branch, high-risk or pre-PR review of implemented work | subagent | `reviewer` (opus) | high |
| Final review of high-risk or large diffs | main session | strongest | high |
| Run tests/builds/linters, report failures | subagent | `test-runner` (haiku) | low |
| Sanity-check a subagent's diff against its task | subagent | `verifier` (haiku) | medium |
Expand Down Expand Up @@ -191,8 +192,7 @@ actually earns its cost:
Opus 5 was a step-change over Opus 4.8 at unchanged
price, and Opus 5.5 is stronger again at 20% less ($4/$20, cache reads
60% less), so the opus tier buys strictly more per dollar than when
this table was tuned - when in doubt between sonnet and opus for
implementation, take opus. That holds on every session model, Fable
this table was tuned. That holds on every session model, Fable
included - see the fable-to-opus bullet below.
- **Opus 5.5 to Sonnet 5.5 is a flat 50% off.** Both read cache at 0.05x
of their own input, so every token type halves: the scout eval profile
Expand All @@ -206,7 +206,12 @@ actually earns its cost:
Opus 5 at `high` on coding, and at `high` it thinks more per turn than Opus 5
did, so the same pin now costs more. That is vendor evidence on
model-level evals, not this plugin's review eval - the pin stays at
high until a medium-vs-high review run on Opus 5.5 is measured.
high until a medium-vs-high review run on Opus 5.5 is measured. The
per-task reviews and scoped re-reviews of a plan loop are the
exception: Superpowers SDD scales their model to the diff with a
mid-tier floor, so they go to `task-reviewer` (sonnet/high) rather than
to `reviewer` with `model=sonnet`, which undercuts its pin. Final, whole-branch, high-risk and
pre-PR review stays on `reviewer`.
- **Tests / verification -> haiku.** Running a command and summarizing
output is mechanical: `test-runner` stays at low effort, and the value
is keeping raw output out of the main context, not the model doing it.
Expand Down Expand Up @@ -414,7 +419,8 @@ with `/model-routing:stats`.
dispatch whose session model cannot be read is left unjudged rather than
guessed at. When
the cheap tier genuinely fits the work, pick an agent pinned for it
(`test-runner`, `verifier`) instead of overriding a role agent downward; the
(`test-runner`, `verifier`, `task-reviewer` for a sonnet-tier review)
instead of overriding a role agent downward; the
dispatch report lists below-pin dispatches in their own section.
- Against the session model, a pin is a ceiling. A pin says "this task never
needs more than X"; the session model says what the user is willing to pay.
Expand Down
Loading