Repository navigation
fix(a2a): removing a peer is one write, and a headerless error is not a mismatch - #490
Conversation
… a mismatch Three robustness follow-ups to peering poll mode. - A peer response with no protocol header counted as version 1 before its status was read, so after a protocol bump a proxy's 502, an unhandled 500 or a non-J5 server would read as "update J5" instead of a retry. Now a missing header counts as version 1 only on a 2xx; an error answer without one goes through normal status handling (`responseProtocolMismatch`, used by direct sends, roster reads, hello and polls). - Removing a peer read, cancelled, dropped and deleted in separate steps, so an ask arriving by poll, a local send or a delivery in that window was missed and could survive re-peering. The removal is now one write transaction that joins the ledger appends. Recording an inbound message (deliver route and poll) and recording a local send to a peer server each check the peer record in their own write, so anything after the removal commits is refused: the deliver route answers 403 peer_not_registered, and a send says the participant is not reachable. - A direct message that was already attempted with no refusal back may be on the peer, so its removal notice now says "may not have been delivered", as a handed-out poll row's does. The delivery worker's peer-cancel path and its drain-wait test hook are gone: the transaction replaces them. Closes #485 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configuration
📒 Files selected for processing (21)
Included review availability: This review used your included allowance. 1 included review remains after this review. Your included PR review attempts over the past 7 days set your current allowance at 3 reviews per hour. 📝 WalkthroughWalkthroughThe pull request changes peer response protocol checks and peer removal. Removal now uses a serialized transaction for exchange drops, delivery cancellation, and peer-record deletion. Inbound and outbound operations check peer records, and delivery notices distinguish possible delivery from confirmed non-delivery. ChangesPeer response protocol checks
Atomic peer removal and delivery handling
Priority: ➖ Normal Estimated code review effort: 4 (Complex) | ~45 minutes Change: Bug fix · Severity of issue fixed: Medium Sequence Diagram(s)sequenceDiagram
participant PeerRemovalService
participant A2ALedgerTransactionWriter
participant SQLite
participant A2ADeliveryWorker
PeerRemovalService->>A2ALedgerTransactionWriter: acquire writer permit
PeerRemovalService->>SQLite: begin transaction and read peer exchanges and waiting deliveries
PeerRemovalService->>A2ADeliveryWorker: query peerAttemptInFlight for direct delivery
PeerRemovalService->>SQLite: append removal events and delete peer record
PeerRemovalService->>SQLite: commit transaction
PeerRemovalService->>A2ALedgerTransactionWriter: publish committed events
Merge Risk: ⚪ Minimal · up to This change makes peer removal a single atomic step and treats proxy error pages as ordinary HTTP failures rather than protocol mismatches. It also gives senders accurate "may not have been delivered" notices. No outstanding defects were found, and the change appears ready to merge. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
Problem
Three robustness gaps in peering poll mode, from Bryant's review and CodeRabbit (Closes #485, part of #399):
What changed
1a: a headerless error is not a mismatch.
responseProtocolMismatchinpeerProtocol.tsreads a missing header as version 1 only on a 2xx. An error answer without a header goes through normal status handling. A real mismatch is still refused with the header, so it is still caught. Every response site uses it: direct send, roster read, hello, and both poller reads.1e: removal is one write.
PeerRemovalService.removedoes everything in one SQLite write transaction:appendEventsInTransaction. They are published only after the commit, and nothing is published if the transaction rolls back.403 peer_not_registered.1f: attempted direct rows get "may not have been delivered". That covers:
attempts > 0and no refusal back;1b and 1d stay unbuilt, as the issue records.
Checklist
peerProtocol.test: responses with no header;PeerPoller.test: a proxy's 502, 503 or 500 with no header is retried. Main's feat(a2a): the peer wire says project #489 bumped the protocol to 2, so without the fix these read as mismatches;PeerPollRoundTrip:PeerRemovalService.test:pr-env.sh --peerand--peer --poll, using GPT-6-Luna Low agents.cross-device.md,a2a/agent-tools.mdand the peering runbook now describe the one-write removal and the wider "may not have been delivered" wording.Claude Opus 5.5 (1M context), in J5 Code through the Claude Code harness.
🤖 Generated with Claude Code
Summary by CodeRabbit