Send a command to a running agent from another device and three things can happen: the command runs, the command fails, or you never find out which. The third case is the one that breaks naive implementations, because the natural recovery (send it again) can apply the effect twice. The fix is a rule about ordering: record the mutation before you dispatch it, and bind that record to an idempotency key and the exact authority that will execute it.
Oompa implements this rule literally. Every effect-bearing command in its sync path is a durable row with a state, an idempotency key, and an authority tuple. The state machine and the admission policy are pure functions in src/cloud/commands.ts, which makes them easy to show and easy to test.
the ordering rule
“Record before dispatch” means the durable write comes first. When you submit a command, the system persists an intent row in pending, and only then does the custodian’s sync cycle claim and execute it. If the process dies between the record and the effect, the record survives and recovery can ask the only question that matters: did the effect run? If the response is lost after the effect ran, replaying the same idempotency key returns the stored outcome instead of running the effect again.
This inverts the usual client intuition. The client does not need to know whether its request succeeded; it needs to know that repeating the exact request is safe. Safety comes from the record, not from the response.
the state machine
Commands move through a closed set of states:
pending ──> prepared ──> effect_started ──> applied
│ │ │
│ │ ├──> failed
│ │ │
│ │ └──> ambiguous
├──> cancelled (applied, failed, ambiguous are terminal)
└──> expired
pending can become prepared, cancelled, or expired. prepared can become effect_started, cancelled, or expired. effect_started can resolve to applied, failed, or ambiguous. Everything except ambiguous from effect_started is terminal, and ambiguous itself is terminal: the transition table lists it with no outgoing edges.
Two details carry the weight. First, effect_started is recorded as its own committed state before the provider effect is attempted to resolve. Once a command is there, the honest answers are applied, failed, or ambiguous, and the code cannot quietly step back to prepared to pretend nothing happened. Second, ambiguous exists as a first-class terminal state. A timeout after dispatch is not a failure; it is genuinely unknown, and the record says so. That record blocks speculative retry, because retrying a possibly-applied effect is how one “steer” becomes two.
replay and conflict
The idempotency check is three lines of policy:
export function idempotencyDisposition(
existing: StoredIdempotency | null,
requestDigest: string,
): IdempotencyDisposition {
if (existing === null) return "new";
return existing.requestDigest === requestDigest ? "replay" : "conflict";
}
new admits the request. replay returns the stored result for a byte-identical request under the same key. conflict refuses: the key was already spent on a different request. That last branch is what makes idempotency keys real keys rather than dedup hints. Reusing a key for a different command is a bug the store rejects instead of a subtle corruption it permits.
Combined with the state machine, this gives the guarantee an agent runtime owes you: every mutation is recorded, replayable by its key, bound to one authority generation, and honest about the difference between “failed” and “unknown.”