Repository navigation
Description
Summary
PR #1132 (merged 2026-05-19) introduced the State & Team Root Resolution and Mode-Switch Check sections to squad.agent.md to fix coordinator awareness of .squad/config.json.teamRoot (closes #1127). The fix correctly resolves the satellite/external-state cases, but it introduces three inconsistencies with the pre-existing Worktree Awareness section that can cause false Init Mode entry in legitimate worktree scenarios and ambiguous behavior in others.
These findings were surfaced during downstream review of the same patch backported into a private dual-root pilot (Inditex). All three are in the upstream prompt as-merged.
Affected file
.github/agents/squad.agent.md (also .squad/templates/squad.agent.md)
Finding 1 — TEAM_ROOT has two contradictory definitions
Where:
State & Team Root Resolutionstep 4 (default branch): "team root is the local.squad/directory" →TEAM_ROOT = <repo>/.squad/.Worktree Awarenessstep 2 (later in the file): "Team root = current worktree root" →TEAM_ROOT = <repo>/.
The same identifier resolves to two paths one level apart depending on which section is consulted. The Mode-Switch Check then probes {TEAM_ROOT}/team.md, which:
- Under section A semantics: looks at
.squad/team.md✅ - Under section B semantics: looks at
<repo>/team.md❌ → triggers Init Mode incorrectly.
Impact: In sessions where the LLM resolves the team root via Worktree Awareness (which Team Mode explicitly tells it to do "on every session start") before the Mode-Switch is consulted, a fully configured repo enters Init Mode. The risk is highest in worktrees without .squad/ committed in the branch — the main scenario Worktree Awareness was originally written to support — because there the State & Team Root step 4 default fails (no local .squad/) and the only correct fallback (discover the main checkout) lives in the section that arrives too late.
Suggested fix: Either
- Make
Mode-Switch Checkprobe{TEAM_ROOT}/.squad/team.mdand defineTEAM_ROOTas the repo/worktree root throughout (preferred — aligns with charter/history path conventions used elsewhere); or - Introduce a separate
STATE_ROOTthat always points at the.squad/directory, and reserveTEAM_ROOTfor the repo root.
Finding 2 — teamRoot path semantics over-restrictive
Where: State & Team Root Resolution step 3.
Current wording: "The team root is the value of teamRoot (absolute path to another .squad/ directory)."
Real-world usage: In our dual-root pilot (and the natural setup for linked repos in the same workspace) teamRoot is a relative path (../cac-vniotsquad) pointing at the repo root that contains its own .squad/ — not at a .squad/ directory directly. The current wording marks portable relative paths as out-of-spec and is ambiguous about which level the path targets.
The note in parentheses "(or {teamRoot}/team.md if teamRoot already points inside .squad/)" acknowledges both shapes exist but does not document how to detect which. Tooling (squad link, squad init --mode remote) accepts both forms.
Suggested fix: Replace step 3 wording with:
teamRootMAY be absolute or relative (relative resolves against the directory containingconfig.json).teamRootMAY point at a repo root (containing.squad/) OR directly at a.squad/directory.- Resolution: if
{teamRoot}/.squad/team.mdexists, use it; else if{teamRoot}/team.mdexists, use it; else error.
Finding 3 — Worktree Awareness step 0 lookup is ambiguous
Where: Worktree Awareness step 0, "Check config.json overrides first — read .squad/config.json in the current directory (or at the git root)".
Problem: Step 1 is where git rev-parse --show-toplevel is invoked, so step 0 cannot yet rely on the git root having been resolved. From a subdirectory the lookup is undefined: do we walk up looking for .squad/config.json? Try CWD first then fall back? Try git root first?
Suggested fix: Specify a deterministic order, e.g.:
- Run
git rev-parse --show-toplevelfirst (move step 1 ahead of step 0, or duplicate the call). - Check
{gitRoot}/.squad/config.json. - If absent, optionally check ancestors of CWD up to
gitRoot(only if multi-.squad/repos are supported — likely not).
Reproduction
The scenarios where this matters in practice:
| Setup | State & Team Root default applies? | Mode-Switch outcome |
|---|---|---|
Normal repo, .squad/ at root, no worktree |
Yes — step 4 returns .squad/ dir |
✅ Passes |
Repo with .squad/config.json.teamRoot set (satellite) |
Step 3 hit — STOP | ✅ Passes |
Worktree of branch where .squad/ IS committed |
Step 4 returns .squad/, but Worktree Awareness later reassigns |
✅ Passes (latent inconsistency) |
Worktree of branch where .squad/ is NOT committed |
Step 4 fails (no .squad/), Worktree Awareness fallback to main checkout would fix but runs too late |
❌ False Init Mode |
Why we're filing rather than patching downstream
We backported #1132 into our dual-root pilot verbatim (per our policy: "verbatim mirror, replace on upgrade to v0.9.5+"). Our specific configuration uses teamRoot (step 3, not affected). We're shipping the backport as-is and would prefer the fix to land upstream so we can drop our local mirror cleanly on the next upgrade.
Happy to open a PR if helpful — let us know which fix shape you'd prefer for finding 1 (collapse TEAM_ROOT to repo root, or split into TEAM_ROOT + STATE_ROOT).
Activity
fix(cli,sdk): state-backend and upgrade regressions (github#1163, git…