routing: route every role to opus, keep model as the escape hatch #75
Labels
No labels
already-shipped
bug
documentation
duplicate
enhancement
good first issue
help wanted
in progress
invalid
needs-decision
proposal
question
wontfix
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: crenshawdev/cadence#75
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Extracted from #63 as part of the 1.5.0 / 2.0.0 split. No config key changes, so no user has to do anything on upgrade. See the objection section below, because #63 explicitly argues this piece should not be extracted, and that deserves an answer rather than a quiet override.
What you want Cadence to do
Route every role to opus in
cadence-core/route-table.json. Keepmodelas a field so it stays an escape hatch, keepmodel.overrides.<role>working, and keepfablereachable only through an explicit override.Why
The current placement is a cost decision wearing capability clothes. Under the shipped
balanceddefault,route-table.jsonputscad-executorat tierstandardandcad-plan-checkerat tierlight, which map to sonnet and haiku. No role needs to be haiku or sonnet for any reason except latency.The evidence already exists informally and should be made formal. Moving an executor to Opus 5 produced fewer loops and fewer bugs in observed use. That is the argument, and it stands without any reframe: a looping executor burns more than the model it saved, so the cheap placement was never actually cheap. The question that matters is not spend per dispatch, it is how many dispatches it takes to get the answer right.
It removes a live inconsistency. While roles are split across model tiers, one
effortvalue in an agent file has to be simultaneously correct for haiku, sonnet and opus. Opus-5-specific guidance cannot be applied to roles that are not routed to opus, which today includes the executor and the plan checker. Collapsing the model axis makes per-role effort meaningful.The objection from #63, stated fairly
#63 argues this cannot be extracted, in these words:
That objection is about framing, not dependency. Technically this change has no relationship to the enum rename: it is a different file, it breaks nothing, and it can be reverted in one commit. And the loop-count evidence is a standalone empirical case that does not need the rigor vocabulary to make sense.
If the framing concern turns out to be the deciding one, the correct response is to close this and fold it back into #63, not to ship it half-argued. Flagging it explicitly so that stays an open choice.
What it costs
This is a behaviour and cost change, and it must not ship silently. No config key changes, which is what makes it minor-release-eligible, but users will see different latency and different consumption. It needs a changelog entry that says so plainly.
Not a cost optimization, and it should not be sold as one. Cadence targets Max subscribers rather than API metering, where the allowance is a ceiling and not a budget. Measured usage on a heavy day (2026-07-27) was 44M billed-equivalent tokens across 11.8 active hours with no weekly cap hit.
Half the burn is out of reach regardless. The orchestrator is the user's own session and Cadence cannot configure it. That was 50.9% of measured burn, so no routing change here touches half the spend, and any claim about totals has to say so.
The measurement that would validate this
Executor loop and retry counts by model. This is the one with an informal result already behind it and it deserves a recorded one.
Files this touches
cadence-core/route-table.json,cadence-core/bin/route.mjsandroute.test.mjs,CHANGELOG.md.Related
Superseded by #81
Closing because the change this issue describes stops existing under #81, rather than because the underlying observation was wrong.
What survives. The seed observation holds: flipping the conventional heavy-plans/cheap-executes assignment and putting the heavier model on the executor produced fewer iterative cycles of bug-finding in adversarial review. That is carried into #81 with a mechanism behind it (Anthropic's Opus 5 guidance: strongest on difficult multi-file work, "completes tasks rather than leaving stubs or placeholders," with a smaller gap on easy single-turn edits) and with the falsifiable prediction that follows from it, namely that the effect should concentrate on heavy phases and nearly vanish on trivial ones.
What does not survive. This issue was scoped as "route every role to opus," which was my reading of #63's wording rather than the actual intent. That framing is wrong twice over:
model.profilea key that is read, resolved, escalated, and has no effect, which is precisely the defect #64 fixed and #78 tracks; deleting the matrix instead is the v2.0.0 breaking change by definition. There is no third option.And the narrow version is not a standalone change either. Moving one role is technically trivial (
cad-executorfromtier: standardtotier: heavylands it on opus underbalancedwith the matrix untouched), but under #81 the executor's model stops being a pinned value and becomes a derived one. Pinning it now would be work undone later.The framing objection this issue reproduced from #63 is therefore moot: the question was never whether "put the executor on opus" could be argued on its own, but whether the model should be pinned at all.