jsconsumer: stop telling responders a stationary ack floor proves a strand

main

Commit

nodo3w ago

OutcomeUncertain's guidance ended "if it has not [advanced], treat it as stranded and follow that runbook" — and that runbook removes the message from the stream. The inference is invalid in the one direction that costs data.

AckFloor is a contiguous watermark: it advances only when the OLDEST unacked message settles, so any older pending message pins it regardless of what happened to this one. This package measures that itself (TestAckFloorStaysStationaryWhileLaterMessagesAck) and reasons from it elsewhere — shouldQuarantine rejects floor+1 as an identification rule for exactly this property — so the doc was contradicting the package's own findings, on the one path where a responder acts destructively.

Only one direction of the check proves anything. Advanced past the sequence: the ack landed, nothing to do. Not advanced: no information about this message. To implicate it the floor has to be pinned AT this sequence — this message is the oldest unacked one — not merely below it because something older has not settled. Until that is established the state stays uncertain, and uncertain is not a licence to remove: the payload is already safe in the DLQ, so waiting costs a pinned floor while guessing wrong destroys the message for every other consumer of the stream. NumAckPending cannot stand in either — an exhausted message pins the floor with it at zero (TestExhaustedDeliveryPinsFloorWithNoAckPending).

Corrected in three places: the OutcomeUncertain contract, the Captured field (which implied the original always needs clearing), and the log line an on-call reads first, which now carries the caveat rather than only the sound direction.

No behaviour change — the outcomes and their triggers are unchanged. What changes is what the docs tell someone to do at 3am.

Refs ENT-1601, ENT-1535, ENT-1492, COR-1257.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com Claude-Session: https://claude.ai/code/session_018qXhU99D2Sxaa32yZWwYRP Entire-Checkpoint: d65fc4a4eb75

Checkpoints

Reconcile jsconsumer Retry Schedule After Broker Semantics

Claude CodeOpus 5.[1m]
View session
Checkpoint 1