Skip to content

fix(coordinator): squad.agent.md does not resolve externalized state — always enters Init Mode #1116

Closed

Description

@ahhlun

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

  1. Initialize a squad in a repository: squad init
  2. Externalize state: squad externalize
  3. Verify .squad/config.json exists with "stateLocation": "external"
  4. Verify team state exists in the external directory (e.g., %APPDATA%\squad\projects\{key}\team.md)
  5. Start a new Copilot session in the repository — the coordinator reads squad.agent.md

Expected Behavior

The coordinator should:

  1. Read .squad/config.json
  2. Detect stateLocation: "external"
  3. Resolve the external state path using projectKey
  4. Find team.md at the external path
  5. Enter Team Mode with the full roster

Actual Behavior

The coordinator:

  1. Checks for .squad/team.md in the local filesystem (line 24 of squad.agent.md)
  2. File does not exist (only config.json remains locally)
  3. Falls through to Init Mode
  4. 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:

  1. Line 24 — The mode-switch check hardcodes .squad/team.md without first resolving external state
  2. Lines 637–649 — The "Worktree Awareness" resolution algorithm has no step for stateLocation: "external"
  3. Line 110 — Reads config.json for stateBackend but ignores stateLocation

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:

  1. Read .squad/config.json
  2. If stateLocation === "external": resolve %APPDATA%/squad/projects/{projectKey}/ as team root
  3. Use that external path for all subsequent .squad/ reads (team.md, routing.md, agents/, etc.)
  4. 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 via resolveExternalStateDir() and loadDirConfig()
  • The .squad-templates/squad.agent.md template has the same issue (should be updated in parallel)
  • The squad externalize command (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

  1. ahhlun commented on May 14, 2026

    @ahhlun
    ContributorAuthor

    PR opened: #1117

  2. self-assigned this
    on May 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions