Repository navigation
Description
Summary
When .squad/ state is externalized via squad externalize, the coordinator agent (squad.agent.md) fails to detect the existing team and erroneously enters Init Mode. The CLI correctly creates the external state directory and leaves a .squad/config.json marker, but the agent governance file's session-start logic never reads this marker.
Steps to Reproduce
- Initialize a squad in a repository:
squad init - Externalize state:
squad externalize - Verify
.squad/config.jsonexists with"stateLocation": "external" - Verify team state exists in the external directory (e.g.,
%APPDATA%\squad\projects\{key}\team.md) - Start a new Copilot session in the repository — the coordinator reads
squad.agent.md
Expected Behavior
The coordinator should:
- Read
.squad/config.json - Detect
stateLocation: "external" - Resolve the external state path using
projectKey - Find
team.mdat the external path - Enter Team Mode with the full roster
Actual Behavior
The coordinator:
- Checks for
.squad/team.mdin the local filesystem (line 24 ofsquad.agent.md) - File does not exist (only
config.jsonremains locally) - Falls through to Init Mode
- Offers to create a new team — even though a fully configured team exists in AppData
Root Cause
Three locations in .github/agents/squad.agent.md need updating:
- Line 24 — The mode-switch check hardcodes
.squad/team.mdwithout first resolving external state - Lines 637–649 — The "Worktree Awareness" resolution algorithm has no step for
stateLocation: "external" - Line 110 — Reads
config.jsonforstateBackendbut ignoresstateLocation
The CLI shipped squad externalize with full SDK support (resolveExternalStateDir(), loadDirConfig() reading stateLocation) but the agent governance file — which is a natural-language prompt, not code — was never updated with instructions for the coordinator LLM to follow this path.
Proposed Fix
Add an "External State Resolution" section to squad.agent.md that runs BEFORE the team.md existence check:
- Read
.squad/config.json - If
stateLocation === "external": resolve%APPDATA%/squad/projects/{projectKey}/as team root - Use that external path for all subsequent
.squad/reads (team.md,routing.md,agents/, etc.) - Skip Worktree Awareness (external state is already branch-independent)
Also update the mode-switch check (line 24) to reference {team_root}/team.md rather than hardcoding .squad/team.md.
Files to Change
.github/agents/squad.agent.md(the only file that needs modification)
Additional Context
- The SDK side (
packages/squad-sdk/src/resolution.ts) handles external state correctly in programmatic code viaresolveExternalStateDir()andloadDirConfig() - The
.squad-templates/squad.agent.mdtemplate has the same issue (should be updated in parallel) - The
squad externalizecommand (packages/squad-cli/src/cli/commands/externalize.ts) works correctly — it's only the coordinator's LLM instructions that are missing the logic - This is NOT a regression (external state was never supported in the agent file) — it's a feature gap between the CLI and the coordinator prompt
Activity
ahhlun commentedon May 14, 2026
PR opened: #1117
fix(coordinator): resolve externalized state, teamRoot, stale work, a…