Skip to content

fix(remote): a project linked to a team repository uses that team (satellite repos) - #2500

Merged
bradygaster merged 3 commits into
devfrom
squad/linked-team
Nov 14, 2026
Merged

bradygaster merged 3 commits into
devfrom
squad/linked-team

Conversation

@bradygaster

Copy link
Copy Markdown
Collaborator

The last failing Claude Code scenario from #2487: a satellite project linked to a team repository.

Problem

After squad link ../team (or squad init --mode remote ../team), squad init --client claude and squad upgrade:

  • scaffolded a placeholder local team in the project: an empty team.md, routing.md, the built-ins' charters, casting, identity and ceremonies;
  • projected Claude Code member subagents from that empty local team, so the linked team's members (here Ripley and Dallas) had no subagents;
  • warned that Copilot's agent file couldn't read a casting pair.

Fix

  • Init and upgrade skip team files in a linked project. This covers the roster, routing, charters, casting, decisions, identity, ceremonies and the built-ins' policies. Project-local state stays: config.json, the launcher, the decisions inbox, logs, sessions and memory. The SDK's initSquad gets a linkedTeam option, and the CLI detects a linked project with linkedTeamSquadDir().
  • Claude members come from the linked team. ClientContext.teamDir points the member projection at the team's squad directory. Charters are still read only inside it, so a linked charter outside the team is skipped. Each member reads its charter and history with squad_state_read, which serves the linked team.
  • Copilot's agent file advertises the linked team's cast.
  • Every coordinator digest gets a Linked team rule in step 1: when config.json sets teamRoot, read team files only through squad_state, never from .squad/ directly, and never create a local roster.
  • Host feature matrix: dual-root-remote-mode is now supported on every host, with Claude validated live. The shared digest gap is split in two: the linked-team half is closed, and the monorepo TEAM_ROOT half stays an expected failure, since this change doesn't add that guidance.

The team repository is never written by the linked project's init or upgrade.

Verification

  • test/claude-linked-team.test.ts:
    • a real init, cast and link, then init and upgrade: no local team files, dallas.md projected from the team, the coordinator carries the rule, and the team repo is byte-identical afterwards;
    • teamDir projection with a symlinked charter outside the team;
    • the digest rule on all 7 hosts.
  • Live (Claude Code, 2026-11-13), in a satellite linked to a team with Ripley and Dallas:
    • the coordinator read the roster and routing via squad_state_read;
    • it routed API work to Dallas;
    • the projected dallas subagent read agents/dallas/charter.md through squad_state;
    • 0 denials, and no files changed.
  • Full suite: the only failures were the known timing flakes (journey, e2e-shell, gh-aw), which pass when re-run alone.

Independent of #2496. Both touch coordinator step 1, so whichever merges second needs a one-line rebase and a plugin regeneration.

🤖 Generated with Claude Code

Copilot AI dynamic review requested due to automatic review settings November 14, 2026 01:06
@github-actions

github-actions Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit aba5f81

PR Scope: 📦🔧 Mixed (product + infrastructure)

⚠️ 3 item(s) to address before review

Status Check Details
❌ Single commit 3 commits — consider squashing before review
✅ Not in draft Ready for review
✅ Branch up to date Up to date with dev
❌ Copilot review No Copilot review yet — it may still be processing
✅ Changeset present Changeset file found
✅ Scope clean No .squad/ or docs/proposals/ files
✅ No merge conflicts No merge conflicts
✅ Copilot threads resolved 4 active Copilot thread(s) resolved (2 outdated skipped)
❌ CI passing 1 check(s) still running

Files Changed (16 files, +520 −289)

File +/−
.changeset/claude-linked-team.md +6 −0
CHANGELOG.md +1 −0
docs/src/content/docs/reference/host-feature-matrix.md +17 −17
packages/squad-cli/src/cli/commands/client.ts +3 −1
packages/squad-cli/src/cli/core/clients.ts +19 −0
packages/squad-cli/src/cli/core/init.ts +11 −4
packages/squad-cli/src/cli/core/upgrade.ts +20 −6
packages/squad-cli/src/cli/shell/lifecycle.ts +4 −2
packages/squad-sdk/src/client/adapters/claude-members.ts +26 −6
packages/squad-sdk/src/client/adapters/coordinator.ts +1 −1
packages/squad-sdk/src/client/adapters/types.ts +6 −0
packages/squad-sdk/src/config/init.ts +219 −206
plugins/squad/agents/squad.md +1 −1
test-fixtures/spec/suite-v0.2/host-feature-matrix.json +40 −44
test/claude-linked-team.test.ts +143 −0
test/clients.test.ts +3 −1

Total: +520 −289


This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.

@github-actions

github-actions Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

🟠 Impact Analysis — PR #2500

Risk tier: 🟠 HIGH

📊 Summary

Metric Count
Files changed 16
Files added 2
Files modified 14
Files deleted 0
Modules touched 5

🎯 Risk Factors

  • 16 files changed (6-20 → MEDIUM)
  • 5 modules touched (5-8 → HIGH)

📦 Modules Affected

docs (1 file)
  • docs/src/content/docs/reference/host-feature-matrix.md
root (4 files)
  • .changeset/claude-linked-team.md
  • CHANGELOG.md
  • plugins/squad/agents/squad.md
  • test-fixtures/spec/suite-v0.2/host-feature-matrix.json
squad-cli (5 files)
  • packages/squad-cli/src/cli/commands/client.ts
  • packages/squad-cli/src/cli/core/clients.ts
  • packages/squad-cli/src/cli/core/init.ts
  • packages/squad-cli/src/cli/core/upgrade.ts
  • packages/squad-cli/src/cli/shell/lifecycle.ts
squad-sdk (4 files)
  • packages/squad-sdk/src/client/adapters/claude-members.ts
  • packages/squad-sdk/src/client/adapters/coordinator.ts
  • packages/squad-sdk/src/client/adapters/types.ts
  • packages/squad-sdk/src/config/init.ts
tests (2 files)
  • test/claude-linked-team.test.ts
  • test/clients.test.ts

This report is generated automatically for every PR. See #733 for details.

@github-actions

github-actions Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

🏗️ Architectural Review

Authoritative evidence: scanners from the PR base commit, posted by the default-branch workflow_run reporter.
Results for head commit aba5f813da5dad82644ef0fa1cfc1d27693f2a2f.

⚠️ Architectural review: 1 warning(s).

Severity Category Finding Files
🟡 warning bootstrap-area 3 file(s) in the bootstrap area (packages/squad-cli/src/cli/core/) were modified. These files must maintain zero external dependencies. Review carefully. packages/squad-cli/src/cli/core/clients.ts, packages/squad-cli/src/cli/core/init.ts, packages/squad-cli/src/cli/core/upgrade.ts

Automated architectural review — informational only.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved linked-team handling defects cause incomplete capability projection and roster discovery, inaccurate client status, and generated agents that can lack required context or ignore project-local settings.

6 open issues
What changed in this PR

Makes satellite projects reuse their linked Squad team repository instead of creating a placeholder local team, addressing the Claude Code scenario in #2487.

Changes:

  • Skip team-owned scaffolding during linked-project init and upgrade while preserving project-local state.
  • Project Claude members from the linked team and add shared coordinator guidance for reading team files.
  • Add regression coverage and update the generated plugin, capability matrix, and release notes.
File Description
test/​clients.test.ts Separates linked-team coverage from the remaining monorepo guidance gap.
test/​claude-linked-team.test.ts Tests linked initialization, projection, containment, and team preservation.
test-fixtures/​spec/​suite-v0.2/​host-feature-matrix.json Updates remote-mode support and validation evidence.
plugins/​squad/​agents/​squad.md Adds generated linked-team reading guidance.
packages/​squad-sdk/​src/​config/​init.ts Adds an option to skip team-owned scaffolding.
packages/​squad-sdk/​src/​client/​adapters/​types.ts Adds the linked-team directory to client context.
packages/​squad-sdk/​src/​client/​adapters/​coordinator.ts Adds shared instructions for accessing linked teams.
packages/​squad-sdk/​src/​client/​adapters/​claude-members.ts Reads linked member definitions and adjusts bootstrap instructions.
packages/​squad-cli/​src/​cli/​core/​upgrade.ts Skips linked-team scaffolding and refreshes linked cast capabilities.
packages/​squad-cli/​src/​cli/​core/​init.ts Detects linked projects and passes that state into initialization.
packages/​squad-cli/​src/​cli/​core/​clients.ts Resolves and supplies the linked-team projection directory.
docs/​src/​content/​docs/​reference/​host-feature-matrix.md Publishes updated support status and live evidence.
CHANGELOG.md Documents the linked-project behavior change.
.changeset/​claude-linked-team.md Records patch releases for the SDK and CLI.

Review effort: Max (dynamic)

Comment thread packages/squad-sdk/src/config/init.ts Resolved
Comment thread packages/squad-sdk/src/config/init.ts Resolved
* uses a team repository (`squad link`, `init --mode remote`), else null.
*/
export function linkedTeamSquadDir(dest: string): string | null {
const paths = resolveSquadPaths(dest);
bradygaster and others added 3 commits November 13, 2026 20:24
After `squad link` / `squad init --mode remote`, init and upgrade
scaffolded a placeholder local team (empty roster, routing, built-ins,
casting) and Claude Code's member subagents came from it, so the
coordinator saw an empty team.

- init/upgrade skip team files in a linked project; local state stays.
- Claude member subagents are projected from the linked team
  (ClientContext.teamDir) and read their charters via squad_state.
- Copilot's agent file advertises the linked team's cast.
- Every coordinator digest gets a "Linked team" rule: read team files
  only through squad_state, never create a local roster.
- Host matrix: dual-root-remote-mode supported on every host (Claude
  validated live); the monorepo TEAM_ROOT digest gap stays open.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- squad client list expects the linked team's member files
- a linked member's charter is carried in its subagent file; history via
  squad_state_read only when its authored tool list allows (never widened)
- effort overrides come from the project's own config
- teamRoot "." is not a linked team in the coordinator rule
- init advertises the linked team's cast in Copilot's agent file
- the interactive shell reads the linked team's roster

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@bradygaster
bradygaster merged commit 7cd97e8 into dev Nov 14, 2026
31 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants