Every Read Convenience Is a Second Send
Delta's read path is built to try hard. A pooled keep-alive connection that turns out dead is replaced and the request retried; a LAN route that fails mid-request is dropped and the request goes again over the tailnet; when this Mac's own Delta is down, kit_delta reads the peer's gateway directly; and the cache can answer without asking anyone. For a read, every one of those is free: reading a thumbnail twice changes nothing.
For a write, each of them is a second send. If the first send reached the owner and only the answer was lost, the retry writes the note twice, or (with compare-and-swap) is refused as a conflict for a write that actually happened. So the write call gives up every one of those conveniences. Delta's invariant 11 says it plainly: a write call is sent at most once, and Delta says whether it left.
The Line That Matters: Did It Leave?
A remote write can fail in three places, and only one of them is ambiguous. PeerClient.call is built around that line:
| Where it failed | Outcome | What the app does |
|---|---|---|
| Before the request left: no route, a connect that fails or is on hold, a ticket that cannot be minted, a certificate that does not match, this Mac's own Delta down | unavailable (the kit: local_delta_down when it is this Mac's Delta), at once; the detail ends "nothing was sent" | Nothing was written. Try again later, or tell the person. |
| After it left, with no answer: a cut, or silence past the time limit | outcome_unknown, HTTP 502 | Ask the owner by the request id. Never send a new request. |
| The owner answered | its result, or its refusal under its own name and status, passed through as it came | Read the answer. |
Everything before conn.request(...) is wrapped so that any exception becomes "nothing was sent". One recovery is allowed there: a LAN route that fails before the send is dropped and one freshly chosen route is tried, because the first route carried nothing. After the send, there is no retry of any kind.
A Connection of Its Own
Why does a call refuse the connection pool? A pooled connection that the server closed while it sat idle does not fail when you pick it up. It fails after the request has been written into it, and at that point nobody can say whether the owner read the request before the connection died. Delta's read path papers over this by retrying on a fresh connection, which is harmless for a read. A write call cannot, so it opens a new connection every time (_open_for_call) and uses it once. The kit does the same on loopback: the app's call to its own Delta is a one-use connection too, for the same reason one hop earlier.
The Time Limit, and the One Exception
The caller sets how long the owner may take: X-Delta-Timeout, in seconds, 30 if absent, at most 600; anything else is bad_request before the call leaves. Connecting is bounded separately by Delta's own connect timeouts, so a slow owner and an unreachable one stay different outcomes.
There is exactly one case where a call goes a second time, and it is not a second send of the work. On a Thunderbolt or LAN route the request carries a ticket; if the owner's gateway answers 401, it refused the ticket at the door, before any verb ran. Nothing was carried out. So the call renews the ticket, opens a new connection, and goes once more under it. The owner still carries it out at most once. A 401 on the renewed attempt is passed back as the answer.
No Way Around This Mac's Delta
A read falls back to the peer's gateway when the local Delta is down. A write does not, and cannot: the local Delta and its local token are what vouch for which Mac and which account is asking. An app that went around it would be an anonymous caller. So kit_delta's call() fails with local_delta_down, "nothing was sent", and Soul Vault turns that into canonical_unreachable: nothing was written, and the text stays with the caller. Its outcome_unknown path keeps the request id and says to ask again with the same id, which the store answers with its first result.
Measured, Including the Awkward Second
With the owner's Delta stopped, calls came back unavailable in 5 to 9 ms once the route had fallen to the tailnet; the first caller, who had to drop the LAN route and try the tailnet, waited 0.4 to 1.6 s. One more fact came out of that measurement. A Delta that is told to stop keeps answering until its listeners' next poll returns, about a second, and a write call that arrives in that second is carried out like any other. One did, during the proof: a fixture revision was written into the gap. So "unreachable" begins when the port refuses, not when the stop is sent, and a test that needs the owner gone waits for the refusal.