Spending research budget where it changes a decision
A deeper pass is worth running only where its result could change what happens next. prospect_cost_router applies that test before spending, so a candidate already ruled out on cheap evidence is not researched further, while one whose fate turns on a single unknown is. The same principle governs model spend on calls: a budget check before dialling, and a breaker that skips scheduled work while still answering a live caller.
The test is about the decision, not the price#
The usual way to control research spend is a cap: so many enrichments per day, so many pages per prospect. A cap controls the total and says nothing about which spending was worth it, so the expensive pass runs on the first hundred candidates in the queue rather than on the hundred where it matters.
The routing test is different. Before a deeper pass runs, the question is whether any plausible answer would change the next action. If a candidate is already disqualified by criteria the cheap evidence settled, a richer profile changes nothing and is not fetched. If the whole judgement rests on one unknown — whether they sell into a segment, whether the site is live, whether a named role exists — that is exactly where a deeper pass pays.
Cheap first, and only then expensive#
- Candidate shape — what discovery already returned. Effectively free, and enough to eliminate a large share of candidates outright.
- Published sources — reading what an organisation says about itself. This is where most evidence comes from, and every claim it produces carries its source.
- A deeper pass — routed, not automatic, and only where the result could move the decision.
- Re-research — governed by
prospect_freshness, so a record is refreshed when it has aged rather than every time it is looked at.
The same principle governs the model bill on a call#
Voice makes the argument concrete because a live call spends continuously. Metering is split by modality rather than by total, since audio tokens run about 4× the same model's text rate on input and roughly 2.7× on output, and brief.usage_summary reads the breakdown the SDK actually reports. merge_usage adds every session a call held, because a restart used to bill only the survivor.
| Check | Before what | Behaviour |
|---|---|---|
budget_refusal | An outbound call, and answering an inbound one | A refused inbound hears the spoken closed-line message, not silence |
ai_quota breaker | Any model call after a 429 or a revoked key | Scheduled work is skipped; a caller already on the line is still attempted |
sweep_stale | Continuously, from the engine tick and the worker heartbeat | Holds every provider to the configured cap and charges what it closes |
| Zero-token fallback | Billing a finished call | A call reporting no tokens is charged from its own duration, never at zero |
The breaker's asymmetry is the routing rule in miniature: the same refusal applied uniformly would drop a person mid-sentence to protect a budget. sweep_stale exists because a browser call has no worker to close it and one sat *active* for 24.78 hours.
What the measurements can and cannot say#
GET /api/usage/voice is the per-call profiler. Its useful property is that it reports what was measured and says what was not, rather than filling the gap with an estimate — which is how a wrong figure becomes a trusted one. An early version looked for an input_audio_duration the SDK does not report and recorded 0.0 seconds for every call ever metered.
For prospecting, the saving attributable to routing is UNKNOWN here. No controlled comparison against a flat policy has been run, and the honest position is that the rule is defensible on its logic and not yet on a measured delta. The counting fix described in evidence-first prospecting is a prerequisite for ever measuring it, because headline numbers that stopped at 500 could not have shown the difference.
How the rule fails#
- The decision boundary is wrong. If qualification criteria are badly drawn, the router faithfully avoids spending on the candidates that would have overturned them.
- Cheap evidence is stale. Eliminating on an old published fact is a false economy that freshness rules only partly cover.
- Under-research reads as thoroughness. A short evidence list looks disciplined whether it is disciplined or merely truncated, which is why the record shows what was not established rather than only what was.
- Spending routed by cost rather than by value drifts back into a cap. The test has to stay *would this change the next action*, not *is this the cheap option*.
Questions#
Is this not just lazy evaluation with a business label on it?
Structurally, yes — and that is the point. The work is deferred until something depends on it, and the dependency is a decision rather than a field being read. The label matters because the alternative most teams reach for is a quota, which defers work by arrival order instead.
Why is a live caller allowed past a breaker that stops everything else?
Because the failure modes are not comparable. A skipped scheduled task runs later; a caller refused mid-conversation hears a business hang up on them. The breaker distinguishes the two rather than protecting the budget uniformly.
How would I tell whether routing is working in my workspace?
Look for candidates that were stopped early and never revisited, and for deep passes on candidates that were already disqualified. Both are visible on the prospects screen, and both indicate the boundary rather than the router is at fault.