Skip to content

refactor(a2a): internal names say project - #484

Merged
Jacksondr5 merged 6 commits into
j5/mainfrom
fold/internal-names-say-project
Oct 8, 2026
Merged

Jacksondr5 merged 6 commits into
j5/mainfrom
fold/internal-names-say-project

Conversation

@Jacksondr5

@Jacksondr5 Jacksondr5 commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Problem

Since the ledger was re-keyed (#482), a ledger is keyed by a project, but the code still calls that key a Squadron: squadronId, SquadronId, readSquadron, and about 2,200 more. Part of #412. Stacked on #483.

What changed

Names only. No table, column, route, tool, tool description or JSON key changes, and no migration is added.

  • squadronId → projectId, with compound names following (senderSquadronId → senderProjectId).
  • SquadronId → LedgerProjectId. It stays its own type, apart from upstream's ProjectId: a ledger key is this server's project for a local row and a peer's id for a remote one.
  • Functions and services: readSquadron → readProjectLedger, listSquadrons → listProjectLedgers, ensureSquadron → ensureProjectLedger, J5SquadronCreationLayer → J5ThreadRegistrationLayer.
  • Web: FleetSquadron → FleetLedgerProject, because the Fleet page already has a FleetProject for the sidebar's project.
  • Test names, helper names, fixture ids and code comments follow.
Every identifier rename, with the number of places (79 pairs, 2,214 places)
Rename Places
squadronId → projectId 1002
SquadronId → LedgerProjectId 407
squadronId → ledgerProjectId 107
squadron → project 85
squadron → ledgerProject 36
requestedSquadronId → requestedProjectId 29
squadronName → projectTitle 29
vmSquadron → vmProject 28
squadrons → projects 27
createSquadron → createProjectLedger 26
localSquadron → localProject 24
J5SquadronCreationLayer → J5ThreadRegistrationLayer 23
FleetSquadron → FleetLedgerProject 23
existingSquadronId → existingProjectId 21
senderSquadronId → senderProjectId 15
homeSquadron → homeProject 15
homeSquadronId → homeProjectId 15
crossSquadron → crossProject 14
laptopSquadron → laptopProject 14
ScopedFleetSquadron → ScopedFleetLedgerProject 12
listSquadrons → listProjectLedgers 11
readSquadron → readProjectLedger 11
ensureSquadron → ensureProjectLedger 11
setupSameSquadron → setupSameProject 11
localSquadronId → localProjectId 10
askerSquadronId → askerProjectId 10
projectFleetSquadron → projectFleetProject 9
Squadron → ProjectLedger 9
replierSquadronId → replierProjectId 9
squadron_name → project_title 8
owningExchangeSquadronId → owningExchangeProjectId 7
PlacementSquadronNotFoundError → PlacementProjectNotFoundError 7
SquadronNotFoundError → ProjectLedgerNotFoundError 6
legacySquadronId → legacyProjectId 6
ledgerSquadronId → ledgerProjectId 5
squadronIds → projectIds 5
corruptedSquadronId → corruptedProjectId 5
expectedSquadronId → expectedProjectId 5
FleetSquadronCrew → FleetProjectCrew 5
listForSquadron → listForProject 4
exchangeSquadronId → exchangeProjectId 4
alphaSquadron → alphaProject 4
betaSquadron → betaProject 4
inSquadron → inProject 4
winningSquadronId → winningProjectId 4
setupTwoSquadrons → setupTwoProjects 4
extraSquadronId → extraProjectId 4
foreignSquadronId → foreignProjectId 4
closeSquadronId → closeProjectId 4
seedSquadronAndSpawner → seedProjectAndSpawner 4
ArchiveCrewSquadronMismatchError → ArchiveCrewProjectMismatchError 3
existingSquadronId → existingLedgerProjectId 3
squadronCrews → projectCrews 3
firstSquadronId → firstProjectId 3
secondSquadronId → secondProjectId 3
SquadronRow → ProjectLedgerRow 3
squadronFromRow → projectLedgerFromRow 3
selectSquadrons → selectProjectLedgers 3
remoteSquadronId → remoteProjectId 3
sameSquadron → sameProject 3
receiver_squadron → receiver_project 3
missingSquadronId → missingProjectId 3
squadronError → projectError 3
duplicateSquadronId → duplicateProjectId 3
subjectSquadronId → subjectProjectId 3
makeJ5SquadronCreationLayer → makeJ5ThreadRegistrationLayer 3
squadronKey → projectKey 3
eventSquadronId → eventProjectId 2
wrongSquadron → wrongProject 2
isSquadron → isProject 2
decodeSquadron → decodeProjectLedger 2
missingSquadron → missingProject 2
isSquadronNotFound → isProjectLedgerNotFound 2
SquadronName → ProjectTitle 2
squadronNames → projectTitles 2
squadronCreationProvided → threadRegistrationProvided 2
ParticipantId → LedgerProjectId 1
SquadronId → ParticipantId 1
squadronId → thread 1

The only changes anything outside the code can see

  • Three error tags, which agents read as the code of a tool error and clients read in J5 HTTP error bodies:

    • SquadronNotFoundError → ProjectLedgerNotFoundError
    • PlacementSquadronNotFoundError → PlacementProjectNotFoundError
    • ArchiveCrewSquadronMismatchError → ArchiveCrewProjectMismatchError

    Nothing matches on the old strings: a search of web, mobile, desktop, the CLI, the tests and the docs found no use outside the three class definitions.

  • Three telemetry span names: j5.a2a.ensureSquadron, j5.a2a.placement.ensureSquadron and j5.a2a.agentCrewInstances.listForSquadron end in ensureProjectLedger, ensureProjectLedger and listForProject.

Still on the wire, pending a decision

These keep their names in this PR. They are not an oversight. Jackson has since decided the peer wire fields are renamed; that is #489, stacked on this PR. The capability key stays.

  • Peer wire fields: originSquadronId on a delivery, squadronId in a dropped Exchange's cause, and squadronId and squadronName on a roster entry (packages/contracts/src/j5.ts). They are mapped at peerDeliveryBody.ts, peerRoster.ts, PeerDirectory.ts and PeerInboundService.ts.
  • The j5Squadrons capability key, which a client reads to recognize an older J5 server and which this server reports as false.

Where the word stays, by design

  • Migrations 001 to 031 and their tests, and the j5_a2a_retired_squadron table.
  • The web's two readers for messages stored before the fold (SpawnBrief.tsx, ThreadA2ARenderer.tsx).
  • apps/server/src/j5/a2a/README.md: it describes the Squadron design and needs rewriting, not renaming.
  • Docs and the marketing site, which have their own PRs.

How this was built, and how to check it

The rename is scripted from a written map. The four steps are separate commits on fold/internal-names-say-project-steps, whose tree is identical to this PR's.

  1. Before the script, by hand, with the compiler pointing at every use (6 files). Two types held both a ledger key and upstream's project id, so a plain rename would have given them two members with one name. A type-checker pass over the base tree found exactly these two:
    • StartSpawnBriefInput: squadronId → ledgerProjectId (the declaration and its three callers).
    • The test helper seedTarget's result in DeliveryTransport.integration.test.ts: squadronId → ledgerProjectId (the declaration and 24 uses).
    • agentPersonaLaunch.integration.test.ts passed a squadronId that nothing has read since feat(a2a): a thread's home is its project #482. A rename would have turned it into a second projectId spread over the real one, so it is removed.
  2. The script (118 files). Running it on step 1 reproduces this step's commit exactly. Where a file already had a projectId in scope, the ledger key in scope becomes ledgerProjectId so the two stay apart; a member name still becomes projectId.
  3. After the script, by hand, again from compiler errors (15 files): the peer wire fields put back to their wire names, three uses in files the script skips, and the web type names.
  4. Comments, test wording and five SQL aliases (54 files).

Hand edits to review are steps 1, 3 and 4: git diff 3995271f74 ed6510bfb6 and git diff 7f96b6fec2 ae5a3d176c. Those commits predate the restack; this PR's tree differs from ae5a3d176c only by j5/main's marketing change.

The mechanical check. A script parses every changed file at the base and at the head and compares them token by token, ignoring comments and layout:

  • 2,214 identifier changes in 79 pairs. Every pair is in the map, except three that are explained: an import reordered by the formatter (two) and the removed test input (one).
  • 250 string changes. Outside tests there are 14: the three error tags, the three span names, the type brand, two member names used as type indexes, and five SQL queries whose table alias squadron became ledger and whose column alias squadron_name became project_title. The rest are test titles and fixture ids.
  • 70 places where the token structure differs. 66 are { squadronId } written out as { projectId: ledgerProjectId }, where the member and the thing in scope now have different names. Three are the removed test input. One is a separator the formatter added.
  • No member named twice: a pass over 7,624 object literals, destructuring patterns and types in the changed files found none.

Upstream impact

File FORK.md case
apps/server/src/server.ts 5: J5SquadronCreationLayer is now J5ThreadRegistrationLayer; the case text is updated
apps/server/src/orchestration-v2/runtimeLayer.test.ts, DelegatedCompletionDelivery.test.ts, three *OrchestratorV2.live.test.ts, mcp/toolkits/worktree/registration.test.ts 5: the same layer name in test wiring

No change to what upstream's product does.

How it was checked

  • vp run typecheck in contracts, client-runtime, web, mobile, desktop and server: 0 errors each.
  • vp test run in contracts (564), client-runtime (1,953) and web (5,842): all passed. Server src/j5, src/environment and the launch tests: 1,079 passed.
  • CI on 13a6480 (the head before it was restacked onto refactor(web): plan implementation goes back to upstream's create-then-start #483's merge of j5/main; the restack brought in only main's marketing change): the required job "Format, lint, typecheck, and unit tests" passed, with the whole server suite in three shards (Test Server 1, 2 and 3), the client tests, and format, lint and typecheck.
  • The crew's tester ran base 3995271 and head 13a6480 on one copy of real data: the MCP tool list with descriptions is byte-equal; the Fleet, Inbox (open and answered), Inbox count, Crew proposals, Crew runtime requests and machine roster responses are byte-equal; the schema dump is identical (270 objects, migration 31). ArchiveCrewProjectMismatchError was seen live, and a peer on the base exchanged an ask and a reply with the head.

Checklist

  • One concern: the description has no "also"
  • Tests cover the changed behavior (backend changes ship with focused tests) — no behaviour changes; the existing tests run unchanged apart from names
  • UI changes: before/after screenshots above, and a video for motion or interaction — none; no UI text or layout changes
  • Upstream-owned files: each one is recorded in FORK.md (case text and file-table row) in this PR
  • Upstream product: any change to what upstream's product does has a human decision linked above and a register entry in docs/j5/product/upstream.md — none
  • Surfaces: entry points, clients, providers, contracts, reverse states, connection modes (see AGENTS.md) — contracts: no wire field changes; clients: the three error tags are not matched anywhere
  • Docs: definitions under docs/j5/product/ and user docs rewritten where this changes them — left for the docs PR; this PR edits one identifier in FORK.md

Claude Opus 5.5 (1M context), Claude Code in J5 Code.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Improvements
    • Fleet views and agent workflows now organize and identify activity by project, including project titles and project-scoped crew information.
    • Project-scoped records are used consistently across messaging, delivery, archiving, placement, and participant management. Existing workflow behavior is retained.

Jacksondr5 and others added 3 commits October 8, 2026 00:24
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>
@vercel

vercel Bot commented Oct 8, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
j5-code Ready Ready Preview Oct 8, 2026 6:51am UTC

Request Review

@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). labels Oct 8, 2026
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Jacksondr5
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>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@Jacksondr5
Jacksondr5 changed the base branch from j5/fold-plan-implementation-back-to-upstream to j5/main October 8, 2026 06:50
@coderabbitai

coderabbitai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Review in Change Stack →

✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

This branch was successfully deployed

1 active deployment
Preview — 911e6388 Deployed Oct 8, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL 1,000+ effective changed lines (test files excluded in mixed PRs). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant