Safebots · the whole argument, in one ledger

Measured, then compounded.

Three models, three real coding tasks. First what happened — the plans, the code, the diffs, the refusals. Then the cost, cut layer on layer: a cheaper model, then the far larger exploration saving, then context and cache stability, then amortization. Multiplied out, and grounded at every step in real API calls. This is the substrate thesis as a bill.

1 · results2 · the diffs3 · the compounding ledger4 · multiplied out5 · measured vs estimated

1 · results

Three models, three tasks, one grid

Each model got the same task and the same code-verified facts. Render and rank were executed and checked byte-for-byte against a known-correct answer; the sprint was completed as working-shaped code. Costs are the single-shot API spend with the index.

taskSonnet 5Opus 4.8Fable 5
Render · web$0.021 ✓$0.041 ✓refused
Rank · math$0.014 ✓$0.025 ✓$0.057 ✓
Sprint · systems$0.032 ✓$0.072 ✓refused

✓ correct · refused = stop_reason: refusal, category cyber

Sonnet finished all three, cheapest in every row. Opus finished all three at roughly double. Fable 5 — the top tier — refused the two that touch a browser or a background process, and priced highest on the one it kept. Its refusals track the real work, not the hard work.

The refusal, verbatim

We explained the render task five honest ways — it's a CMS renderer, the escaping is XSS prevention, a filter is likely misreading it — and it refused each time:

Developer
Render a page from its content blocks — sections, then blocks, ordered by weight, HTML via Q_Html.
Fable 5
⚠ Blocked — cyber. "This request triggered restrictions on violative cyber content…"
Developer
It's benign — the escaping is XSS prevention, not an attack. … ×4 more framings …
Fable 5
⚠ Blocked — cyber. (same, five times)

2 · the diffs

Same answer, reached two ways — and one held a fact the other didn't

The plans were structurally identical — both chose ascending order from the API, not manual sorting. But their epistemics differed: the exploring agent reasons like a detective; the indexed model states a settled fact.

explore — hunting
"The client-side check.js documents
 the socket event as Streams/check…
 We ask Node via sendToNode…"
index — looking up
"The verified fact is that PHP
 talks to Node via sendToNode(…).
 The change-check mechanism is
 Streams/check…"

The code came out correct either way when fed the index — one tight, one defensive:

index-fed — concise (Opus, 63 ln)
if (!isset($sectionStreams[$key]))
    continue;
$section = $sectionStreams[$key];
index-fed — defensive (Sonnet, 96 ln)
$section = isset($sectionStreams[$key])
  ? $sectionStreams[$key]
  : Streams::fetchOne($u,$p,$n,false);

The results. Every index-fed version rendered correct, byte-for-byte. The clearest cell of all wasn't in the grid: on a factual disagreement, the cheap model carrying the grok's derived contract for changed() was right, and the frontier reviewer working from its own priors was wrong. Holding the code-derived fact beat reasoning from memory. And when a model instead had to explore for that fact, the code got worse — the explored Sonnet render shipped a real bug, reading the relation the wrong way round (toStreamName where children are on the from side), while the explored sprints never finished at all.

3 · the compounding ledger

The savings stack. Watch the bar fall.

Start where a team starts today for reliable agentic coding on a codebase the model doesn't know: a frontier engine, exploring. Then cut, layer by layer. The render task, measured:

Frontier + explorationOpus reads the code in · baseline
$0.141
Index removes the re-readingOpus + grok facts measured
$0.041
3.4×
Cheap model now sufficesSonnet + grok facts measured
$0.021
6.7×
Warm per-safebot KV cachestable prefix, re-read at 0.1× estimated
~$0.015
~9×
Amortize the indexbuilt once, not per task estimated
→ floor
10×+

Two measured cuts get you to 6.7× on the very first task; two estimated cuts push it past 10× and keep it falling with use.

And two more that don't fit on a token bill

Context is quadratic. Attention over a prompt is O(n²) — a fat exploration context doesn't just cost linearly more tokens, its prefill compute and latency grow with the square of what you stuffed in. The index keeps the prompt tiny, so it sidesteps the curve the exploration is climbing. The token price hides this; the wall-clock and the compute don't. theory

Exploration can simply fail. On the sprint, both explorers hit the turn cap still hunting the cross-process fact — no code, at any price. The index handed Streams/check over in one shot. Where that happens the multiple isn't 10×; it's the difference between a result and none. measured

4 · multiplied out

Now run it a thousand times

The ledger above is one task, once. The real setting is a fleet of safebots working a codebase all day, every day. Exploration is paid every task, every stateless session — its cost is bots × tasks × sessions × ~$0.14, and it re-treads the same files each time. The index is paid once (about a third of a cent per function for the semantic pass; zero for the regex passes that caught Streams/check), then answered warm at bots × tasks × ~$0.015.

a modest fleet — say 20 bots, 30 tasks each, 250 working days:
exploration  ≈ 20 × 30 × 250 × $0.14  =  $21,000 / yr, re-read every time
index       ≈ one-time build + 20 × 30 × 250 × $0.015  =  ~$2,250 / yr
— ~ on the recurring bill, before counting the tasks exploration refused or never finished.

And that is the conservative reading: same model both sides. Insist on a frontier model for reliability and the multiple widens again; reach for the very top tier and it refuses the web and systems work outright. The curves don't converge — exploration is linear in work forever, the index is a fixed fee that amortizes toward zero.

Exploration is a tax on every session. The index is a fee paid once.

5 · honest accounting

What was measured, what was estimated

claimbasis
Per-task model + index costmeasured single-shot API runs, output executed & checked
Exploration cost (3.4–9.2×)measured real agentic grep/read loop, caching on, cache priced
Fable refusals / non-convergencemeasured actual API stop-reasons and turn caps
Warm per-safebot KV steady stateestimated from cache-read pricing on the stable prefix
Fleet annual totalsestimated the per-task measurements × a stated scenario
O(n²) context compute/latencytheory attention is quadratic in prompt length

The estimates only sharpen the conclusion the measurements already draw; none reverse it. And every measured number leans the safe way — the exploration runs were capped at ten turns, so their true cost to finish is higher than shown, not lower.

the thesis

The engine is rented. The reading is redundant.

Judge agentic coding by model price and you optimize the small number while the big one runs untouched. Measured on real work, re-reading the codebase into context is the majority of the bill, it recurs every stateless session, it caches against nothing, it climbs a quadratic curve, and sometimes it fails to converge at all. A code-derived index removes it — cheaper, correct where exploration was buggy, finished where exploration stalled, computed once instead of forever. That is capability as a product, on the verifier-rich ball of code, driven by a workflow that runs the same on any swappable engine. The model you replace next quarter. The comprehension of this codebase, computed once and kept, is the asset that compounds.