model-router
Skill1 starsChanged 39 days agoMITView on GitHub
Scores task capability and verification needs on separate axes, then routes execution to the worker or architect subagent; also sets the project's model ladder. Triggers: 'route this task', 'which model should handle this', 'does this need the architect'.
- Reads credentials
17 other projects use a version of this.
Adopted by
Most recently taken up by
- tance-mang/chinese-webnovel-skillstheir own version, first seen Nov 8, 2026
- hamzzaqureshi/gravidextheir own version, first seen Nov 8, 2026
- uniqaiapp/model-routertheir own version, first seen Nov 1, 2026
- francoisdp/skillstheir own version, first seen Oct 22, 2026
- yosukekurita-rgb/model-routertheir own version, first seen Oct 20, 2026
- Zelray/hermes-model-routertheir own version, first seen Oct 20, 2026
Other versions17 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 17
- tance-mang/chinese-webnovel-skills★ 97same name
- nidhi-singh02/agent-router★ 87same name
- RandomNest/aivideo-production-skills★ 15same name
- manishk753/claude-model-router★ 3same name
- francoisdp/skills★ 2same name
- NorkzYT/claude-code-autopilot★ 2same name
- hamzzaqureshi/gravidex★ 1same name
- mehtab78/skills★ 1same name
- Zelray/hermes-model-router★ 1same name
- benagesjustin-boop/model-router★ 0same name
7 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository23 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- harness-auditSkill
- skill-benchSkill
- ask-biginSkill
- bigin-harness-setupSkill
- contract-syncSkill
- debug-workflowSkill
- discovery-workflowSkill
- epic-workflowSkill
- flutter-figma-handoffSkill
- go-scaffoldSkill
- knowledge-distillSkill
- napkinSkill
- next-scaffoldSkill
- nodejs-scaffoldSkill
- nuxt-marketing-scaffoldSkill
- nuxt-scaffoldSkill
- nuxt-ui-figma-handoffSkill
- project-scaffoldSkill
- session-handoffSkill
- sprint-distillSkill
- task-workflowSkill
- write-testsSkill
The file
We split this skill into the rules it gives an agent
2 rules. 0 are common, 0 are distinctive, and 2 are very specific to this project.
0
Common
Most of the 16 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
2
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 127
After the subagent returns, check it against the payload's definition-of-done (contract: references/agent-invocation.md's "Return …
- Very specific: line 133
Never spawn bigin-skills:verifier from this step — that's a separate, task-workflow-only mechanism scoped to auditing a diff against …
“Common” is measured: kept by at least 6 in 10 of the 16 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
model-router
Scores a task, then hands it off to the matching subagent. Two implementer tiers plus the verifier — effort is fixed per agent, the model is whatever the project's profile resolves to.
| Tier | balanced (default) | frontier |
| Worker | worker — sonnet/high | worker-frontier — opus/medium |
| Architect | architect — opus/medium | architect-frontier — opus/high |
| Verifier | verifier — sonnet/high | verifier — sonnet/high |
The agent varies by profile, not just the model: effort comes only from an agent file's frontmatter (the Agent tool has no effort parameter), so a profile pinning a tier at a different effort routes to a variant agent. Read both off routing.agents[tier] and routing.models[tier] — never assume the agent from the tier name.
Two axes, scored separately, because they answer different questions:
- Capability picks the tier, and therefore the model. Raise it when the model had the context, clearly tried, and still got it wrong.
- Verification sets the gate discipline in the spawn payload, and never touches the model. Raise it when the failure was a skipped file, unrun tests, or a refactor abandoned partway.
Breadth, coverage, and blast radius are verification signals. Spending them on a bigger model over-provisions routine work (a 30-file rename is not hard, just wide) and under-provisions small-but-hard work (a one-file bug in an unfamiliar subsystem is the case that actually wants a stronger model).
Mechanical signals come from scripts/classify.mjs. The capability signals are mostly not mechanically detectable and must be reasoned about directly — never invent them from a diff.
When not to use
- The user already named both the tier and the model for work they want done right now ("use opus for this") — honor that directly instead of re-scoring. Setting the project's standing ladder in
.claude/model-routing.jsonis this skill's job, so that request does belong here. - The spec-format decision —
task-workflow's full-spec tier fires only on an explicit request, never on perceived complexity. This skill only picks the executing tier once work is about to start (an already-produced full-specPLAN.mdis an automatic architect-tier signal).
Step 1: Gather mechanical signals
Routing happens before work starts, so pass the planned scope — the files you're about to change, from PLAN.md or the user's description:
node ${CLAUDE_SKILL_DIR}/scripts/classify.mjs --paths "path/one.ts,path/two.ts"Relay the JSON. Fields: scope, filesChanged, touchedFiles, highRiskMatches, testCoverageRatio, plannedNewFiles, fullSpecDetected, routing.
testCoverageRatio is measured over existing, non-test files whose type the script can look a test up for: .js .jsx .ts .tsx .mjs .cjs .vue .go .py .dart .rs (an allowlist). Everything else — docs, config, .env*, .sql, .html, YAML, styles, assets — is left out of the ratio, so a scope with none of those code types reports null ("no code touched"), not 0. New code files in the planned scope (same allowlist) are reported separately as plannedNewFiles and excluded from the ratio; a new doc or config file is in neither — a file with no code in it can't be "untested", and folding it in produced a 0 that read as a risk signal when it only meant "new". A scope that is entirely new files therefore also reports null. Deleted files (in uncommitted/branch scope) stay in touchedFiles and highRiskMatches but are neither planned new files nor counted for coverage. Backslash paths are normalised to /.
With no --paths the script falls back to uncommitted changes, then the branch diff — correct mid-task, wrong at the start. scope tells you which it used:
planned/uncommitted/branch— signals are real, use them.none— a clean tree with no planned scope.filesChanged,highRiskMatches,testCoverageRatio, andplannedNewFilescome backnull, meaning unknown, not zero. Never score anullas 0 pts — that's what made every fresh task look trivial. Either re-run with--paths, or estimate from the stated scope in Step 2.- On an
errorfield (non-git repo, nogitonPATH) — same handling asnone.routingis still populated with the default profile either way.
Step 2: Assess capability signals (reason directly, no tool)
- Is there a pattern to follow? An equivalent already in this codebase, something similar needing real adaptation, or nothing — a new pattern/abstraction.
- Is there a structural judgment call? More than one reasonable way to structure this, where the choice matters, versus one obvious shape.
- Is the problem understood? Requirements and cause clear, some ambiguity left, or an unfamiliar domain / unknown root cause.
These predict capability. Note what's not here: reversibility and blast radius moved to Step 3b, where they belong.
Step 3: Score capability → tier
Auto-overrides — skip scoring, go straight to Architect:
fullSpecDetectedis true (PLAN.mdcarries the[full-spec]marker oftask-workflow's full-spec tier — an explicit user signal; FR/NFR citations alone don't count)- The change is a breaking contract change, or a data migration that transforms existing rows
- The root cause is unknown (a bug whose cause you can't yet name, in code or a domain the worker would be learning on the job) — the "problem understood" row at its top value. Small scope doesn't make it safe: this is where a stronger model gets it right and a cheaper one confidently fixes the wrong thing
A non-empty highRiskMatches is not an override. It's a prompt to ask whether the second bullet applies — additive contract changes and version bumps touch the same paths and are ordinary edits. What high-risk paths do change is the verification bar (Step 3b).
Otherwise, score:
| Signal | 0 pts | +1 | +2 | +3 |
| Pattern to follow | An equivalent exists in this codebase | Similar, needs real adaptation | None — needs a new pattern/abstraction | |
| Structural judgment | One obvious structure | More than one reasonable structure, and the choice matters | ||
| Problem understood | Requirements and cause are clear | Some ambiguity to resolve | Unfamiliar domain (root cause unknown is an auto-override) | |
| Simultaneous context | ≤2 files | 3–9 files | 10+ files |
Total 0-4 → Worker · 5+ → Architect.
Full tables plus five worked examples: references/scoring-rubric.md.
Step 3b: Set the verification bar (independent of tier)
From the mechanical signals — this changes what the payload demands, never which tier or model runs:
| Trigger | Bar |
highRiskMatches non-empty | Verifier round mandatory even where task-workflow would skip it; full gate output; revert path in PLAN.md |
testCoverageRatio < 0.3, or null with code changes | Tests first, per write-tests' TDD ordering |
plannedNewFiles non-empty | Tests first, same ordering — a new module has no coverage by construction, not by neglect |
filesChanged ≥ 5 | Gates across the whole tree, not just touched files |
| Flaky/timing symptom | ≥5 consecutive passes (see debug-workflow's race-conditions.md) |
| None of the above | Normal gates: lint + typecheck + tests on the touched scope, each run's pass/fail summary line shown |
Triggers stack.
Step 3c: Resolve the model and the agent for that tier
The tier decides which rung; the profile decides both the model and the effort on it. Take both from Step 1's routing:
- Model —
routing.models[tier]. Precedence:- On-demand instruction in this request ("run it on fable", "use the frontier ladder here") — this spawn only. Don't edit the project config for a one-off.
routing.models[tier]from Step 1 (resolved from.claude/model-routing.json).- The
balanceddefault, which is whatroutingalready reports when no config exists.
- Agent —
routing.agents[tier], which is thesubagent_typefor Step 5. Don't derive it from the tier name. Effort can't be passed at spawn time, so a profile that pins a tier at a different effort routes to a variant agent instead: underfrontierthe worker tier isworker-frontierand the architect tierarchitect-frontier. Spawning the base agent there would silently run the task at the wrong effort. The verifier resolves toverifieron both profiles today — read it offroutinganyway, since that is what changes when a ladder does.
routing.efforts[tier] reports the effort that agent carries; it's informational (state it in Step 4), never something you pass. If a user asks for a different effort level, say so plainly — there is no way to honor it at the call site.
Relay any non-empty routing.warnings to the user — a malformed config degrades silently to the default otherwise, and a config the user thinks is active but isn't is worse than no config. Setting effort in .claude/model-routing.json is one of those warnings: it isn't a supported key.
Profiles, config schema, and the effort rationale per model: references/model-profiles.md.
Step 4: State tier + agent + model/effort + verification bar + rationale
One line: the chosen tier, the agent that will run it, its model and effort (and where they came from if not the default), the verification bar from Step 3b, and the deciding signal(s). Name the agent whenever it isn't the tier's base — "Worker tier → worker-frontier on opus/medium (frontier ladder)" tells the user what they're actually paying for; "Worker tier" alone doesn't. Only ask the user (single yes/no) if the capability score sits exactly on a bucket boundary and the Step 2 signals were ambiguous — don't ask by default, that reintroduces the triage overhead this skill exists to remove.
Step 5: Spawn
Call the Agent tool with subagent_type: bigin-skills:<routing.agents[tier]> and model: <resolved model from Step 3c> — both from Step 3c, and pass model explicitly on every spawn, even when it matches the agent's frontmatter default, so the handoff and the actual run can't disagree. Pass: one-line task scope, PLAN.md path if one exists, the touched-file list, the chosen tier + rationale, the Step 3b verification bar, and — if graphify-out/graph.json exists in the repo — a note of its presence plus a docs/graph-usage.md pointer, so the subagent knows why it was picked, can flag a mismatch, and navigates structurally before grepping. Also pass objective, constraints, and definition-of-done — a fixed payload template, not prose advice, so Step 6 has something concrete to check the return against. The verification bar belongs in definition-of-done, so an unmet bar is a Step 6 gap rather than a footnote.
Exact call shape and payload fields: references/agent-invocation.md.
Step 6: Return evaluation
After the subagent returns, check it against the payload's definition-of-done (contract: references/agent-invocation.md's "Return evaluation contract").
- Met — proceed to Step 7 (or use the result directly if nothing else applies).
- Partial/unmet — resume the same subagent (
SendMessageto its agent ID, not a fresh Agent call) naming the specific gap against the definition-of-done. Track the cycle count in your own working context — max 2 follow-up cycles (3 dispatches total, including the original spawn). - Cycle cap hit:
- Either tier → surface to the user, with every prior return and the gaps named; don't retry further and don't escalate tiers on this path.
- Never spawn
bigin-skills:verifierfrom this step — that's a separate,task-workflow-only mechanism scoped to auditing a diff againstPLAN.md. This evaluation is deliberately lighter than a verifier round. - Never auto-escalate into the architect tier from exhaustion — it is reachable via Step 3's capability score or its auto-overrides (
fullSpecDetected, a breaking contract change or row-transforming migration, an unknown root cause), not by exhausting the worker tier. A worker that hits a real architectural decision says so withROUTING_MISMATCH:(Step 7).
A ROUTING_MISMATCH: reply at any point during this loop short-circuits straight to Step 7 — re-scoring wins over continuing the retry loop, since a wrong tier makes definition-of-done checks meaningless.
Step 7: Handback protocol
If the spawned subagent reports a routing mismatch (a reply starting ROUTING_MISMATCH: — see references/agent-invocation.md), re-score with the new information and respawn the correct tier (re-running Step 3c for the new tier's model). Don't try to change the running subagent's model or effort mid-session — both are fixed once it's spawned, not mutable in place.
References
scripts/classify.mjs— mechanical signal gathering (--pathsfor planned scope) + model-ladder resolution; never outputs a suggested tier.references/model-profiles.md— profiles,.claude/model-routing.jsonschema, override precedence, effort rationale per model.references/scoring-rubric.md— both axes in full (capability point table, verification-bar triggers) + 5 worked examples.references/agent-invocation.md— Agent tool call shape, payload fields (objective/constraints/definition-of-done), return evaluation contract, handback contract.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

