Gap
Cloud treats client_nonce as a body-bound DM idempotency key, but the terminal generates a fresh nonce for each send and retains it only for the current call. When the response is lost, it says to inspect the conversation manually. After a restart or an accidental resend, the user can create a second message because the original nonce is gone.
Evidence: send with generated nonce, Cloud nonce conflict contract, Cloud send path.
Outcome
- Record a bounded account/conversation-scoped pending-send receipt before the first request, with its original nonce and body digest. Avoid writing message text to a general log or plain transcript cache.
- On uncertain delivery, reconcile by the canonical DM event/read path or a narrowly scoped nonce lookup. If absent and the user retries the same text, reuse the original nonce; never allocate a new nonce for an uncertain send without an explicit new-message choice.
- Show
sending, saved/admitted, saved/blocked, and unconfirmed as distinct states. Preserve the typed admission reason without implying the model ran merely because the message was saved.
- Expire and clear resolved receipts safely, including after account switch.
Acceptance
Simulate a server commit followed by a lost response, process crash, timeout before commit, body mismatch under the same nonce, and account switch. The shared DM has at most one copy of the intended message, and the terminal accurately reports what is known. No automatic retry repeats a model turn under a new nonce.
Scope / dependency
Message delivery reconciliation, using the canonical Online DM. Depends on replay/read-back in #235; it does not add offline model execution.
Gap
Cloud treats
client_nonceas a body-bound DM idempotency key, but the terminal generates a fresh nonce for each send and retains it only for the current call. When the response is lost, it says to inspect the conversation manually. After a restart or an accidental resend, the user can create a second message because the original nonce is gone.Evidence: send with generated nonce, Cloud nonce conflict contract, Cloud send path.
Outcome
sending,saved/admitted,saved/blocked, andunconfirmedas distinct states. Preserve the typed admission reason without implying the model ran merely because the message was saved.Acceptance
Simulate a server commit followed by a lost response, process crash, timeout before commit, body mismatch under the same nonce, and account switch. The shared DM has at most one copy of the intended message, and the terminal accurately reports what is known. No automatic retry repeats a model turn under a new nonce.
Scope / dependency
Message delivery reconciliation, using the canonical Online DM. Depends on replay/read-back in #235; it does not add offline model execution.