A ladder of executors: cheap first, escalate only with a reason
Who does a task should follow from the kind of task, not from mood. Start at the cheapest level that can do it, and allow a step up only with a reason from a short closed list. Log the reason, so you can later count whether the senior call changed anything.
π― For A team lead who routes work between scripts, cheap models and senior models
- A four-level ladder from script to senior arbiter
- Why escalation needs a coded reason and what the list looks like
- How to measure whether escalation pays
πͺ The idea
Without a rule, work drifts to the most capable executor because that is the one people trust. It is also the most expensive and the slowest. A ladder replaces habit with a rule: each class of task has an entry level and a ceiling, and the choice is made by code, not by a model.
Our levels are four. Level zero is no model at all: a linter, a script, a database query. Level one is a low-cost model for volume. Level two is a mid-level model for harder single tasks. Level three is a senior arbiter for the rare decision.
π Escalation needs a reason
A step above the entry level is allowed only with one of five reason codes: a deterministic check failed, two junior runs disagree, the task is an architecture decision, the task touches the money path, or the operator asked. Any other reason is refused. "Just in case" is not on the list, because that is exactly how the expensive executor ends up doing everything.
Two details matter. Where a task is a pure check, a failed check is a fact, not a reason to call a senior: the script said no, so fix the cause. (A junior's work that fails a deterministic check is a different case, and it is one of the five listed reasons.) And the reason goes into the trace of the call, so the ledger can say not only what an escalation cost but why it happened.
π Ceilings from measurement
Per-call cost ceilings are not guesses. We read the highest observed cost per call from thirty days of traces and set the ceiling at twice that for level one and four times for levels two and three. A ceiling is a runaway detector, not a price list: it catches a loop long before it becomes a bill.
π¬ What the ledger shows
Our metered transport records the level and the escalation reason of each call. On 3 November 2026, 21:53 UTC it held 10,062 rows at level one costing $15.76 in total, and 32 rows at level three costing $0.38. Level two had 0 rows. 54 rows carry no level; all of them fall inside three minutes on 22 September 2026. Only 18 rows carry an escalation reason, all "operator request", and they sit on level-one rows. None of the 32 level-three rows carries a reason.
That is a gap in our own practice, found while writing this page. The rule says a senior call needs a coded reason, and the ledger shows senior calls with none. We have not yet traced whether those calls bypassed the router or were logged before the field was enforced, and we will not guess here. The lesson is to check your own log against your own rule.
π The kill rule
We decided in advance what would end the ladder. We count the share of level-two and level-three calls that changed the result. If it stays under twenty percent for sixty days, the ladder collapses to two levels. The senior calls then are not paying for themselves. We have not yet collected enough escalations to apply the rule, and we say so.
π οΈ Practice: write your own ladder
- List your task classes, for example check a file, summarise a ticket, review a design.
- For each class pick the entry level and the ceiling level. Put level zero first wherever a script can decide.
- Write the closed list of escalation reasons. Keep it under six.
- Make the router refuse any escalation without a listed reason and write the reason to the call trace.
- Set per-call cost ceilings from the highest cost you have actually seen.
- Choose a kill rule and a date before you start.
β Check yourself
- Ask for a senior call with no reason. The router refuses.
- You can list last week's escalations and the reason for each. If a senior call has no reason, you know why.
- A failed linter run does not trigger a model call.
- You can state the share of senior calls that changed the result, or you say that you cannot yet.
π§ When this does NOT work
- Too few escalations. A rule about "share that changed the result" needs a sample. With so few logged reasons it is only a trend.
- Reasons that become habit. If every call says "architecture decision", the list is decoration. Review the reasons monthly.
- Hard tasks that start hard. Some classes should enter at a high level. Say so in the config.
- Cheap level doing damage. A low-cost model on a task that needs judgement saves little and costs trust.
- A ladder without a ledger. If you do not log level and reason, you cannot learn anything from it.
π Evidence
| What we measured | Rows, cost, level and escalation reason in our metered transport ledger |
| When | 3 November 2026, 21:53 UTC |
| Artifact | The transport ledger database: 10,062 level-one rows, 32 level-three rows, 18 rows with a reason; the ladder configuration file and its test |
| Limit | The ledger covers the metered lane only. The kill rule has not been applied yet |
β‘οΈ Next
Count the cost of the levels in Costs, budgets and limits, and see what the routing control changes in Models and routing.
Sources
- Costs, budgets and limits: budgets per task.
- Models and routing: what routing changes.
- Splitting work across agents, and when not to: swarms.
- AI judging: why βit says it is doneβ is not acceptance: acceptance by checks.
π Article connections
Open the full knowledge graph βPublished article links. Select a node to open its article at the heading.
Article links Β· keyboard / text view
Same topic
- A vector base is a map, not a source: what we learned from retrieval
- When you cannot tell what a model call cost: freeze, then reconcile
- Splitting a big task for a cheap model: the 24,000-byte lesson
- Skills, MCP tools and rules: three ways to give an agent capabilities
- Eight shell and git mistakes our agents made, and the rule for each
- Several agents, one repository: ownership rules from real incidents
Next steps
Related reading
A vector base is a map, not a source: what we learned from retrieval
A vector base finds passages that are close in meaning to your question. It does not know which are true or current. Treat every hit as a pointer: open the file it names, check the hash, and take numbers from the artifact, never from the retrieved paragraph.
AI agents and MCP explainedWhen you cannot tell what a model call cost: freeze, then reconcile
Sometimes a model call times out and you do not know whether the provider charged you. Never record that as zero. Mark it uncertain, stop new paid calls, and let a named person reconcile it with the provider's statement. Refusals before generation are the exception.
AI agents and MCP explainedSplitting a big task for a cheap model: the 24,000-byte lesson
A cheap model does well on one small, well-defined job and badly on a big pile. We cap a task at 24,000 bytes and refuse larger ones before any model is called. Split by unit, one file or one country per task, and check the size before you start.
AI agents and MCP explainedSkills, MCP tools and rules: three ways to give an agent capabilities
Agents get abilities in different ways. A rule constrains what they do, a skill tells them how to do a job, and an MCP tool lets them call a function. Each has its own risk, so declare all three in a register and test that nothing exists unlisted.
π¬ Comments