"'I might have paid and I have nothing to show for it' is a real state. Give it a name."
The State Most Systems Refuse to Model
The paid submission moves through a small state machine: preparing → submitting → completed. That looks tidy. But there's a fork most designs pretend doesn't exist, and it's the one that costs money. Picture the executor in submitting: it sent the request, then the connection died before any response came back. What is the state now?
You genuinely do not know. The provider may have received the request, run the transcription, and charged for it — the response just never made it home. Or the request may have never arrived at all. From where Recall stands, those two worlds are indistinguishable, and they have opposite financial consequences. Pretending it's a success loses the result; pretending it's a clean failure invites a retry that could double-charge. The honest answer is: this is a third thing, and it needs its own name.
Name It, Don't Guess It
Recall calls it ambiguous, and models it as a real, terminal-until-resolved state. The rules are precise:
completedreturns the stored response with no new call — the safe, already-paid path.submittingwith a saved provider response in the executor's outbox is completed from that saved response (next lesson) — no new charge.submittingwith no saved response isambiguous: maybe billed, maybe not, no result in hand.
And the crucial rule: an ambiguous call is never automatically retried. A blind retry is a coin-flip bet with real money — heads you needed it, tails you just paid twice. So Recall stops and routes the uncertainty to a human. A person checks the provider's actual billing record, learns which of the two worlds is real, and resolves the call explicitly: it was not billed (safe to redo), or it was billed but lost (accept the loss, don't redo for free), or it was billed and you genuinely need to pay again (a separate, explicit authorization). The machine refuses to guess where guessing spends money.
Why a First-Class State Beats a Best Guess
The temptation is always to collapse ambiguity into success or failure so the code has fewer branches. That tidiness is exactly the bug. Uncertainty that you fold into 'probably failed, retry' silently authorizes double-spending; uncertainty you fold into 'probably fine' silently loses data. Modeling the ambiguous state as its own named thing — parked, un-retried, waiting for a human with access to ground truth the machine doesn't have (the provider's billing) — is what keeps the money honest. When a machine can't know, the right move isn't a confident guess; it's an explicit 'I don't know' that a human can resolve.