This repository was archived by the owner on Aug 10, 2026. It is now read-only.
fix(agent): re-enable the CAS single-claim guard (channelQueueStoreFor dropped ifUpdatedAt) - #128
Merged
Conversation
…he CAS single-claim The production adapter wiring the pull-queue to a VaultTransport (channelQueueStoreFor, daemon.ts) declared `setInboundStatus` as a 3-param arrow `(id, status, claimedAt) => vt.setInboundStatus(id, status, claimedAt)` — silently DROPPING the 4th `ifUpdatedAt` arg. VaultTransport.setInboundStatus does a CAS (`if_updated_at`) only when that arg is present, else falls back to `force:true` (last-write-wins). So in production every claim was force:true → the compare-and-set single-claim guard (agent#101, the whole point of PR #116) was SILENTLY DISABLED, and the double-claim race (two connected sessions grabbing the same inbound) was re-opened for channel-backend agents. The bug was invisible to the type checker (a narrower arrow is assignable to the wider interface slot) and to the tests (they inject a FAKE ChannelQueueStore that honors all four args — only the live daemon adapter was lossy). Fix: forward all four args. New test exercises the REAL adapter against a VaultTransport (records the PATCH body): with ifUpdatedAt → `if_updated_at` CAS (not force); without it → `force:true` (the release/handled/sweep path, unchanged). Found by the agent-module deep audit. Gate: typecheck clean; `bun test ./src` 1022 pass / 0 fail. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The bug (found by the deep audit — production correctness)
The single-claim guard (agent#101 / PR #116) — which stops two connected sessions from both claiming the same inbound message — was silently disabled in production.
channelQueueStoreFor(daemon.ts) wired the store'ssetInboundStatusas a 3-param arrow that dropped the 4thifUpdatedAtarg:VaultTransport.setInboundStatusdoes a compare-and-set (if_updated_at) only whenifUpdatedAtis supplied, otherwiseforce:true(last-write-wins). With the arg dropped, every claim took theforcepath → CAS off → the double-claim race re-opened forchannel-backend agents.Why nothing caught it: the type checker can't (a narrower arrow is assignable to the wider interface slot), and the unit tests inject a fake
ChannelQueueStorethat honors all four args — only the live daemon adapter was lossy.Fix
Forward all four args (one line). Plus a new regression test that exercises the real adapter against a
VaultTransport(records the PATCH body):ifUpdatedAt→if_updated_atCAS body (notforce)force:true(the release/handled/sweep path — unchanged)This is the test class the audit flagged as missing: assert the production adapter, not just the fake store.
Gate
tsc --noEmitclean;bun test ./src1022 pass / 0 fail.