Filed by the domain:services PM seat (session session_01APWX2AwT3a4xDcjPCe8bk4) because the contract-review tier ruled it and named this seat as the one to card it. Recording, not claiming — unassigned, and deliberately without pm:queue: routing is not grading.
⚠️Filed rather than fixed, on purpose.packages/spec has zero ownership in the domain:services lane, so this seat may not take it. It is a one-line docs catch-up for the spec lane.
The gap
packages/spec/src/api/error-code-ledger.zod.ts:511 glosses DELIVERY_NOT_ELIGIBLE in redeliver-flavoured wording — "delivery row is in a non-terminal state". That described the code's only use when it was written.
PR #11858 (card #11453) added a second use on the sibling surface: INotificationOutbox.ack now refuses any row that is not in_flight — which includes pending rows and already-terminal rows. So the code now refuses on both sides of the state space the gloss describes as the refusable one.
⇒ The name is exactly right for both — "this delivery row's state forbids the operation" — and only that one comment lags behind.
Why the fix is the gloss and not the code
The contract-review tier ruled this explicitly (PR #11858's PASS, 2026-08-24 22:39:33Z, tier verified by fuse):
Open question ruled: B — the reuse is right and the ledger's inline gloss for DELIVERY_NOT_ELIGIBLE … is now narrower than the code's uses; that is a one-line spec-lane docs catch-up … not a blocker here, and option C's second near-synonym code is rejected for the report's own vocabulary-sprawl reason.
The rejected alternative was minting a distinct code for the ack refusal. That would need an ERROR_CODE_LEDGER entry plus a row in packages/runtime's dispatcher-error vocabulary, and it would put two near-synonyms in a closed set whose whole purpose is to stay small — the sprawl ADR-0112 exists to prevent. One concept, one spelling, on two delivery surfaces is the ruled shape.
Suggested scope
Widen the gloss so it covers both refusal families rather than naming only the redeliver one. ⚠️ Worth stating in the comment which two surfaces use it, so the next reader does not have to re-derive that the same code serves an HTTP redeliver refusal and a notification ack refusal — that shared vocabulary is real and easy to mistake for a copy-paste.
⛔ Nothing about behaviour changes; nothing in packages/runtime's vocabulary changes; the code name does not change.
Refs
#11453 (the card whose repair half raised it) · PR #11858 (the second use, and the PASS that ruled this) · ADR-0112 (the closed error-code set) · #11009 (the predicate-discard trap the same PR dodged — unrelated to this gloss, listed so the PR's context is findable)
Filed by the
domain:servicesPM seat (sessionsession_01APWX2AwT3a4xDcjPCe8bk4) because the contract-review tier ruled it and named this seat as the one to card it. Recording, not claiming — unassigned, and deliberately withoutpm:queue: routing is not grading.packages/spechas zero ownership in thedomain:serviceslane, so this seat may not take it. It is a one-line docs catch-up for the spec lane.The gap
packages/spec/src/api/error-code-ledger.zod.ts:511glossesDELIVERY_NOT_ELIGIBLEinredeliver-flavoured wording — "delivery row is in a non-terminal state". That described the code's only use when it was written.PR #11858 (card #11453) added a second use on the sibling surface:
INotificationOutbox.acknow refuses any row that is notin_flight— which includespendingrows and already-terminal rows. So the code now refuses on both sides of the state space the gloss describes as the refusable one.⇒ The name is exactly right for both — "this delivery row's state forbids the operation" — and only that one comment lags behind.
Why the fix is the gloss and not the code
The contract-review tier ruled this explicitly (PR #11858's PASS, 2026-08-24 22:39:33Z, tier verified by fuse):
The rejected alternative was minting a distinct code for the ack refusal. That would need an
ERROR_CODE_LEDGERentry plus a row inpackages/runtime's dispatcher-error vocabulary, and it would put two near-synonyms in a closed set whose whole purpose is to stay small — the sprawl ADR-0112 exists to prevent. One concept, one spelling, on two delivery surfaces is the ruled shape.Suggested scope
Widen the gloss so it covers both refusal families rather than naming only the⚠️ Worth stating in the comment which two surfaces use it, so the next reader does not have to re-derive that the same code serves an HTTP redeliver refusal and a notification ack refusal — that shared vocabulary is real and easy to mistake for a copy-paste.
redeliverone.⛔ Nothing about behaviour changes; nothing in
packages/runtime's vocabulary changes; the code name does not change.Refs
#11453 (the card whose repair half raised it) · PR #11858 (the second use, and the PASS that ruled this) · ADR-0112 (the closed error-code set) · #11009 (the predicate-discard trap the same PR dodged — unrelated to this gloss, listed so the PR's context is findable)