You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Status: proposal for discussion. Nothing here is decided.
The question
Should J5 retire the Squadron as a concept separate from upstream's project, and attach the J5 behavior that hangs off Squadrons (the A2A ledger, Exchanges, placement, Crews, the Fleet page) to projects instead?
Why this came up
A new-thread UX question (the Squadron picker opening before every new thread) kept turning into a question about the Squadron itself. The Squadron was meant to work like an epic that spans several folders, which doesn't fit upstream's one-folder-one-project model. Multi-folder support was deferred, and so far there's no need for it. Meanwhile, keeping the Squadron mechanically separate from (though built on) projects has real costs:
Settings. Projects are hidden everywhere except settings, so the person meets a noun there that the rest of the app never shows them.
Shared projects. Two Squadrons can reference one project. That is a class of bugs upstream's model doesn't have, and a case no one uses.
Fork cost. 19 of the 58 cases in FORK.md touch Squadrons, including the largest new-thread seams (16, 19). Four entries in the register of divergences (D8–D11) exist only because a Squadron isn't a project. D11 is why scheduled tasks created in the UI can't start threads.
Open work. Around 15 open issues exist only because of the split (listed below).
The use case the Squadron was built for, several separate efforts on one repository, can already be covered inside one project by separate sets of agents and Crews. It isn't clear we'd outgrow that.
What we found
Measured against one live install, read-only:
Every Squadron references exactly one project. No project is shared by two Squadrons. No thread sits in a project its Squadron doesn't reference.
About half the live threads have no Squadron home. That looked like a bug, but isn't:
110 are provider-native Subagents (Codex and Claude workers, plus one delegate_task child). By definition they aren't participants and get no home.
Measured against upstream (our pin 67a2be0 and current main6414268):
Upstream allows one active project per folder. Retiring Squadrons loses "two separate efforts over one repository, each with its own name." Today that only exists as an unused capability.
A thread's project is fixed when the thread is created.projectId is set only by thread.create; thread.metadata.update can't change it. Drafts can change project before their first send, client-side only. So the Registrar's rule that "a home never changes" maps directly onto a thread's project.
Upstream now has threads without a project
Upstream merged these after our pin, so they arrive with the next upstream advance:
It is still a project: each environment gets one "No project" project (projects.ensureScratch), and each of its threads gets its own folder under <home>/scratch/. So the rule that a thread's project is fixed at creation still holds.
Ways in: the draft heading's project menu, the palette's New thread in... list (which the sidebar "+" still opens), a palette action, a mod+alt+n hotkey, the no-projects screen, and mobile.
Moving out: a no-project draft reads "What should we work on?" and can be moved into a project before it is sent.
Under projects, these features arrive as upstream built them.
Under Squadrons, every no-project thread needs a Squadron home, or send refuses. Supporting it means one of three things, each new fork work:
an automatic Squadron for the "No project" project, which the Squadron definition forbids (no default "junk drawer");
letting these threads go without a home, which leaves them out of the ledger and every Squadron filter;
hiding the feature.
It lands on Squadron seams. The PR rewrites:
DraftHeroHeadline, which J5 replaces wholesale (D8);
the palette's New thread in... list;
the new-thread shortcuts in _chat.tsx;
the no-projects screen;
mobile's new-task picker.
The next advance conflicts on all of them either way. Under Squadrons, each one also has to be converted again.
It closes a gap D9 records. Requiring a folder rules out non-coding work. "No project" and name-only projects cover that upstream.
Upstream keeps the picker on "+". The new-thread friction that started this discussion is upstream's too.
If we fold, things to decide about no-project threads:
Accept upstream's default container? "No project" is the unnamed default the Squadron definition rejected as a junk drawer. It's probably fine, since upstream aims it at throwaway work, but it reverses a recorded decision and should be named as one.
One shared partition. All no-project threads on an environment share one project. That means one ledger partition and one Fleet group. Under upstream's same-project rule, agents in unrelated scratch threads could also archive each other or merge back.
Hidden in J5 dev servers. Upstream withholds the feature when the home is inside a Git checkout, which is the case for a worktree's .j5code. Testing it needs a home outside a checkout.
What the change would be
Projects become the unit the person picks, filters by, and organizes around, as they are upstream. The J5 UI built for Squadrons goes back to upstream's project UI:
Create Squadron
the first-run Squadron gate
the welcome wizard's Squadron stage
the sidebar Squadron scope
the Squadron picker, draft chip and headline
the Squadron label on thread cards
J5 features re-key from Squadron to project:
the A2A ledger, Exchanges and the placement tree
Crews
the Fleet page
Peer Agents inheriting their spawner's home, which already lands them in the spawner's project
Agent-to-agent communication stays unbounded. "Never a boundary on communication" still holds; nothing about it depends on the Squadron.
Archive and merge-back checks collapse into upstream's existing same-project rule.
Removed:list_squadrons and join_squadron. Every thread already has a project.
Docs: the Squadron product definition is retired. The glossary, overview and register entries D8–D11 are rewritten. The FORK cases that exist only for Squadrons are removed as their code goes.
The Squadron name as a fleet-native noun. Keeping "Squadron" as a UI label on projects would keep paying the fork cost D8 justified only by the many-to-many shape.
Migration (has to work for every live install)
J5 is live for more than one person, so this would need a migration that runs on each environment's server against data we can't see. Cases it would need a rule for:
One Squadron, one project. The normal case: the Squadron's ledger, memberships, placement and Crews move to the project.
Several Squadrons on one project. Merge their ledgers into the project, refuse to migrate, or something else? Their names would be lost or need a home.
One Squadron with several projects. The UI caps creation at one folder, but the server's create path accepts a list.
A Squadron whose project was deleted.
A Squadron name that differs from its project's title. Keep the project title, or offer to rename the project?
Mixed versions. Clients read Squadrons from every connected environment (the j5Squadrons capability). The mobile app ships separately and can talk to servers on different versions.
One-way. As with the V2 database cutover, it should be safe to snapshot before and roll back by restoring the snapshot.
Open questions
Is "several efforts on one repository" something we want to keep supporting, by some means other than Squadrons?
Should the ledger re-key to project ids, or keep a hidden one-to-one partition per project? Re-keying is cleaner. A hidden partition is a smaller migration, but keeps the separation this proposal is trying to remove.
What should the migration do with shared-project and multi-project Squadrons on other installs?
Do any other installs actually have shared-project Squadrons? Knowing that would settle question 3.
If we keep Squadrons, how should upstream's no-project threads get a home? If we fold, do we accept "No project" as upstream ships it?
The new-thread picker change that started this is parked until this is decided. If projects come back, the friction becomes upstream's own (the picker opens when there is more than one project), and any change to it would be a much smaller divergence.
Status: proposal for discussion. Nothing here is decided.
The question
Should J5 retire the Squadron as a concept separate from upstream's project, and attach the J5 behavior that hangs off Squadrons (the A2A ledger, Exchanges, placement, Crews, the Fleet page) to projects instead?
Why this came up
A new-thread UX question (the Squadron picker opening before every new thread) kept turning into a question about the Squadron itself. The Squadron was meant to work like an epic that spans several folders, which doesn't fit upstream's one-folder-one-project model. Multi-folder support was deferred, and so far there's no need for it. Meanwhile, keeping the Squadron mechanically separate from (though built on) projects has real costs:
FORK.mdtouch Squadrons, including the largest new-thread seams (16, 19). Four entries in the register of divergences (D8–D11) exist only because a Squadron isn't a project. D11 is why scheduled tasks created in the UI can't start threads.The use case the Squadron was built for, several separate efforts on one repository, can already be covered inside one project by separate sets of agents and Crews. It isn't clear we'd outgrow that.
What we found
Measured against one live install, read-only:
delegate_taskchild). By definition they aren't participants and get no home.Measured against upstream (our pin
67a2be0and currentmain6414268):projectIdis set only bythread.create;thread.metadata.updatecan't change it. Drafts can change project before their first send, client-side only. So the Registrar's rule that "a home never changes" maps directly onto a thread's project.Upstream now has threads without a project
Upstream merged these after our pin, so they arrive with the next upstream advance:
projects.ensureScratch), and each of its threads gets its own folder under<home>/scratch/. So the rule that a thread's project is fixed at creation still holds.mod+alt+nhotkey, the no-projects screen, and mobile.<home>/projects/<slug>with a README, an icon and a first commit, then opens a thread there.Why this matters for the proposal:
Another reason to fold.
It lands on Squadron seams. The PR rewrites:
DraftHeroHeadline, which J5 replaces wholesale (D8);_chat.tsx;The next advance conflicts on all of them either way. Under Squadrons, each one also has to be converted again.
It closes a gap D9 records. Requiring a folder rules out non-coding work. "No project" and name-only projects cover that upstream.
Upstream keeps the picker on "+". The new-thread friction that started this discussion is upstream's too.
If we fold, things to decide about no-project threads:
spawn_agentpasses (see spawn_agent puts every Peer Agent in the caller's branch and worktree #274). Not yet checked..j5code. Testing it needs a home outside a checkout.What the change would be
list_squadronsandjoin_squadron. Every thread already has a project.Lost:
Migration (has to work for every live install)
J5 is live for more than one person, so this would need a migration that runs on each environment's server against data we can't see. Cases it would need a rule for:
j5Squadronscapability). The mobile app ships separately and can talk to servers on different versions.Open questions
Issues this would close or reframe
The new-thread picker change that started this is parked until this is decided. If projects come back, the friction becomes upstream's own (the picker opens when there is more than one project), and any change to it would be a much smaller divergence.
🤖 Generated with Claude Code