Blocked-by: #12651
Filed unassigned by the dev seat working #12651 (branch claude/issue-12651-ipubsub-delivery-docblock), no repair attempted there — both sites are outside that card's PM-declared file surface (packages/spec + generated artifacts + cluster.mdx), and each lives in a different package, so touching them would pull two more build/test/gate surfaces into a prose-only spec PR.
What #12651 changes
IPubSub's contract docblock (packages/spec/src/contracts/cluster-service.ts) stops claiming "At-least-once delivery; handlers MUST be idempotent" and states the shipped guarantee driver-relatively instead: delivery is whatever the configured driver declares, no shipped driver exceeds at-most-once, a missed message is expected, handlers must be idempotent and tolerate loss.
The two sites that go stale when it lands
1. packages/core/src/security/authz-invalidation-channel.ts:45-51 — a present-tense assertion about the interface that becomes false:
⚠️ Known contradiction in the surrounding docs, recorded so nobody resolves it the wrong way: IPubSub's own interface docblock (@objectstack/spec/contracts) still says"At-least-once delivery", which no shipped driver provides. cluster.mdx §4.2 and the redis driver are the measured statements and are the ones this module follows. Repairing that docblock is a packages/spec change and is filed separately, deliberately not made here.
This paragraph declares its own expiry condition — "filed separately" is #12651. Once that lands the paragraph reads as a live contradiction that no longer exists, which is worse than no note at all: the next author goes looking for a disagreement between the interface and the drivers and finds none. The rest of that docblock (the at-most-once reasoning, the TTL-is-the-bound rule, the publish-site best-effort note) stays correct and should be left alone; only the "known contradiction" paragraph retires, ideally replaced by a plain pointer to the now-honest interface docblock.
2. packages/services/service-cluster/src/memory/pubsub.ts:18 — the memory driver's behaviour list:
- At-least-once semantics held vacuously (a single in-process delivery).
This is a claim about a guarantee the contract no longer makes, so it is at minimum a dangling reference. It is also arguably wrong on its own terms: the same docblock says handler errors are swallowed and logged via onError, so a throwing handler loses the message with no retry and no persistence — which is not at-least-once in any sense, vacuous or otherwise. The honest statement for this driver is the one the corrected interface already implies: synchronous single in-process delivery, no cross-process reach, no replay.
Not in scope here
packages/triggers/trigger-api/src/api-trigger.ts:31 also says "At-least-once delivery", but about inbound API-trigger events per ADR-0041 — a different subject on a different transport. Checked and deliberately excluded; it is not part of this cleanup.
Suggested handling
One small PR after #12651 lands, touching the two files above. Prose only, no behaviour change. Sizing note for whoever picks it up: the two files sit in @objectstack/core and @objectstack/service-cluster, so it carries those two packages' gate families rather than the spec ones.
Blocked-by: #12651
Filed unassigned by the dev seat working #12651 (branch
claude/issue-12651-ipubsub-delivery-docblock), no repair attempted there — both sites are outside that card's PM-declared file surface (packages/spec+ generated artifacts +cluster.mdx), and each lives in a different package, so touching them would pull two more build/test/gate surfaces into a prose-only spec PR.What #12651 changes
IPubSub's contract docblock (packages/spec/src/contracts/cluster-service.ts) stops claiming "At-least-once delivery; handlers MUST be idempotent" and states the shipped guarantee driver-relatively instead: delivery is whatever the configured driver declares, no shipped driver exceeds at-most-once, a missed message is expected, handlers must be idempotent and tolerate loss.The two sites that go stale when it lands
1.
packages/core/src/security/authz-invalidation-channel.ts:45-51— a present-tense assertion about the interface that becomes false:This paragraph declares its own expiry condition — "filed separately" is #12651. Once that lands the paragraph reads as a live contradiction that no longer exists, which is worse than no note at all: the next author goes looking for a disagreement between the interface and the drivers and finds none. The rest of that docblock (the at-most-once reasoning, the TTL-is-the-bound rule, the publish-site best-effort note) stays correct and should be left alone; only the "known contradiction" paragraph retires, ideally replaced by a plain pointer to the now-honest interface docblock.
2.
packages/services/service-cluster/src/memory/pubsub.ts:18— the memory driver's behaviour list:This is a claim about a guarantee the contract no longer makes, so it is at minimum a dangling reference. It is also arguably wrong on its own terms: the same docblock says handler errors are swallowed and logged via
onError, so a throwing handler loses the message with no retry and no persistence — which is not at-least-once in any sense, vacuous or otherwise. The honest statement for this driver is the one the corrected interface already implies: synchronous single in-process delivery, no cross-process reach, no replay.Not in scope here
packages/triggers/trigger-api/src/api-trigger.ts:31also says "At-least-once delivery", but about inbound API-trigger events per ADR-0041 — a different subject on a different transport. Checked and deliberately excluded; it is not part of this cleanup.Suggested handling
One small PR after #12651 lands, touching the two files above. Prose only, no behaviour change. Sizing note for whoever picks it up: the two files sit in
@objectstack/coreand@objectstack/service-cluster, so it carries those two packages' gate families rather than the spec ones.