Repository navigation
feat(a2a): the peer wire says project - #489
Merged
Merged
Conversation
The welcome wizard loses its Squadron stage and imports into projects as upstream does. Branding and the Providers label stay. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Squadrons are retired (#412). The agent-to-agent ledger is keyed by project id, every thread except a provider Subagent is a participant in its own project, and everything an agent or a person reads says project. Migration 031 re-keys and renames the ledger in place: the Squadron table is never dropped, so nothing cascades, and no row is added, removed or renumbered. It refuses by name a project that several Squadrons share, keeps a record of the old ids and names, leaves a peer server's ids alone, and aborts if any table's row count changes or any row is left without a project. Registration moves off the launch path to the stored thread.created event, which every creation writes, including the two importers that bypass the thread.create command. A server that upgrades registers the threads it already has, and a caller without a home registers on its first agent-to-agent call. list_squadrons, join_squadron and the Squadron routes are removed. Tools, routes and contracts carry project ids and titles. A client refuses a server whose ledger is not keyed by project. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…n-start Implementing a proposed plan in a new thread used J5's single launch so the new thread could inherit its plan parent's Squadron. A thread's home is now its project, so there is nothing to inherit. ChatView's function is upstream's again: create the thread, start the turn with the plan reference, and delete the thread if the start fails. The launch request and its contract lose sourcePlanRef. J5's launch never passed the reference to the first message, so the plan was not marked completed; upstream's message dispatch does. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
5 of 7 tasks
Jacksondr5
force-pushed
the
fold/peer-wire-says-project
branch
2 times, most recently
from
October 8, 2026 06:26
33125f0 to
6c808dd
Compare
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Jacksondr5
marked this pull request as ready for review
October 8, 2026 06:45
The ledger has been keyed by project since the re-key, but the code still called its key a Squadron. This renames the leftover internal names: squadronId becomes projectId, the SquadronId type becomes LedgerProjectId, and the functions, services, errors, test helpers and comments follow. No table, column, route, tool or JSON key changes, and no migration is added. Three error tags that agents read in tool errors change with their classes: ProjectLedgerNotFoundError, PlacementProjectNotFoundError and ArchiveCrewProjectMismatchError. The peer wire fields and the j5Squadrons capability key keep their names. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Two peered J5 servers named a project a Squadron on the wire between them: originSquadronId on a delivery, squadronId in a dropped Exchange's cause, and squadronId and squadronName on a roster entry. They are now originProjectId, projectId and projectTitle, and the translation at the boundary is gone. The fields are required, so the peer protocol version becomes 2. Two connected servers have to be updated together: an older one is refused by the version check before its request is read, in both directions, and is named as the one to update. Messages queued for it are retried, not dropped. Migration 032 renames the fields inside a stored roster snapshot, so a polling peer's agents stay listed until it next sends its roster. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Jacksondr5
force-pushed
the
j5/fold-internal-names-say-project
branch
from
October 8, 2026 06:45
13a6480 to
edc79a1
Compare
Jacksondr5
force-pushed
the
fold/peer-wire-says-project
branch
from
October 8, 2026 06:45
6c808dd to
1b12862
Compare
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Jacksondr5
changed the base branch from
j5/fold-internal-names-say-project
to
j5/main
October 8, 2026 07:01
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
This was referenced Oct 8, 2026
This was referenced Oct 8, 2026
This branch was successfully deployed
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 join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Problem
After #484 the only place a project is still called a Squadron in running code is the wire between two peered J5 servers:
originSquadronIdon a delivery,squadronIdin a dropped Exchange's cause, andsquadronIdandsquadronNameon a roster entry. Jackson decided to rename them now, while nobody runs peer servers. Part of #412. Stacked on #484.What changed
originProjectId,terminal.cause.projectId, and a roster entry'sprojectIdandprojectTitle.peerDeliveryBody.ts,peerRoster.ts,PeerDirectory.tsandPeerInboundService.tspass the fields through under one name.Release note: two connected J5 servers must be updated together
A server on this version and a server on the previous one stop exchanging messages until both are updated. A message queued for the other server is not dropped and its Exchange stays open. Where this server sends to the other one, the delivery is retried, and if the other server stays on the older version it ends as an alarm, like any delivery that keeps failing. Where this server stores for a polling peer, the message waits to be handed out, with no retry and no alarm.
Where this server connects to the other one (direct mode, and the polling side of poll mode):
list_participantsleave that server's agents out and count it inunread_peer_count.On a server that stores messages for a polling peer, it looks different, because this server never connects to that peer:
list_participantskeeps listing the poller's agents from the roster it last sent, and does not count it inunread_peer_count.An older peer is refused by the version check before its request body is read, in both directions and in both link modes, so it never fails as a schema error.
Stored data
Unchanged
The
j5Squadronscapability key stays, reported asfalse. It is what makes an older client show its J5 views as unsupported.Upstream impact
None. Every file is J5-owned. FORK.md case 48 (peering) is updated for migration 32 and protocol 2.
How it was checked
vp run typecheckin contracts, client-runtime, web, mobile, desktop and server: 0 errors each.PeerRoundTrip.test.tsruns two real servers' peer layers against each other. Poll mode:PeerPollRoundTrip.test.tsdoes the same with one side polling.PeerHttp.test.tssends hello, roster, deliver and poll requests on another version, and a delivery that states none; each gets 409 with the update message and nothing is recorded.PeerRegistryService.test.tsrefuses an unversioned hello when a peer is added.PeerOutbound.test.tsgets a protocol-1 server's answer to a delivery; the row is retried, the Exchange stays open, and the peer's record names it as the one to update.PeerPoller.test.tsdoes the same for a poll.PeerDirectory.test.tscovers a roster read from a server on another version, using a newer one (3 against 2); the compare is the same function for both.PeerOutbound.test.tsbuilds the request body from the stored delivery row and assertsoriginProjectId; no stored row carries a wire field name.032_PeerRosterSaysProject.test.tsrenames a protocol-1 snapshot, keeps its agents in order and its hash, leaves a peer with no snapshot alone, and the result decodes with the wire schema.j5/main's marketing change): the required job "Format, lint, typecheck, and unit tests" passed, with the whole server suite in three shards, the client tests, and format, lint and typecheck. The first head failed CI typecheck on one line of the new migration test, which is fixed.unread_peer_count1; a deliver request each way got 409peer_protocol_mismatch, not a schema error; nothing crossed.Checklist
FORK.md(case text and file-table row) in this PR — none toucheddocs/j5/product/upstream.md— noneAGENTS.md) — contracts: the peer wire; connection modes: direct and poll peering both covereddocs/j5/product/and user docs rewritten where this changes them — left for the docs PR; this PR edits FORK.md case 48 onlyClaude Opus 5.5 (1M context), Claude Code in J5 Code.
🤖 Generated with Claude Code