Repository navigation
Description
Summary
squad preset apply <name> lays down agent folders and charters on disk, but does not populate the three coordinator-facing index files that make the team visible to the Squad coordinator. The result: a brand-new repo looks correctly scaffolded to squad doctor, but the coordinator's session-start mode-switch check sees an empty ## Members table and treats every session as Init Mode — i.e., "no team exists, let me propose one."
Verified on squad v0.10.0, Windows, with squad preset apply geektime.
Repro
mkdir test-preset && cd test-preset
squad init
squad preset apply geektime
# open any Copilot session in this dir and ask "show me the team"
# coordinator responds with empty roster and offers to cast a new teamExpected behavior
After squad preset apply <name>, the preset's agents are fully registered:
.squad/team.md## Memberstable has one row per preset agent (Name | Role | Charter path | Status)..squad/casting/registry.jsonhas an entry per cast-eligible agent (excluding the always-named Scribe/Ralph/Rai) withpersistent_name,universe,created_at,legacy_named: false,status: "active"..squad/casting/history.jsonhas the assignment snapshot recording the universe selection..squad/routing.mdhas its{Name}/{domain}placeholder tokens replaced with the preset's actual cast and role mapping.
Actual behavior
After squad preset apply geektime (which ships 7 agents — Picard, Data, Worf, Crusher, Scotty, Uhura, Scribe):
.squad/agents/{picard,data,worf,crusher,scotty,uhura,scribe,ralph,Rai}/— all created correctly with validcharter.md+history.md✅.squad/team.md:## Members | Name | Role | Charter | Status | |------|------|---------|--------| ← zero rows
.squad/casting/registry.json:{ "agents": {} }.squad/casting/history.json:{ "universe_usage_history": [], "assignment_cast_snapshots": {} }.squad/routing.md: still contains{Name}and{domain 1}/{domain 2}placeholder tokens.
Coordinator impact
Per squad.agent.md mode-switch logic:
Yes, but
## Membershas zero roster entries → Init Mode (treat as unconfigured — scaffold exists but no team was cast)
So even though the agents are on disk with full charters, the coordinator:
- Cannot see the team (every session opens in Init Mode and asks the user to propose a roster).
- Has no routing mapping (placeholder tokens — routing falls back to "pick someone").
- Has no persistent-name reservations (empty registry → a follow-up cast could collide with existing names).
- Has no universe lock on file (overflow handling / migration logic has nothing to reference).
squad doctor blind spot
Doctor reports everything green on this broken state:
✅ team.md found with ## Members header — file present, header found
✅ agents/ directory exists — directory present (9 agents)
✅ casting/registry.json exists — file present, valid JSON
Summary: 10 passed, 0 failed, 0 warnings, 2 info
Doctor checks file existence and ## Members header presence, but does not check that the Members table has any rows or that the registry is populated when cast-eligible agent folders exist.
Suggested fix
1. squad preset apply should finalize wiring
After copying agent folders, the apply step should:
- For each agent in the preset manifest:
- Append a row to
.squad/team.mdMembers table:| {name} | {role-from-charter} | .squad/agents/{name}/charter.md | active | - If the agent is cast-eligible (i.e., not Scribe/Ralph/Rai), upsert into
.squad/casting/registry.json:"{name}": { "persistent_name": "{Name}", "universe": "{universe-from-preset-metadata}", "created_at": "<ISO timestamp>", "legacy_named": false, "status": "active" }
- Append a row to
- Append the assignment snapshot to
.squad/casting/history.jsonwith a uniqueassignment_id, the chosen universe, and the cast list. - Resolve
{Name}/{domain}tokens in.squad/routing.mdfrom the preset's role-to-name mapping. (Each preset should declare its routing table — or this can be derived from charters by matching**Role:**against the standard routing categories.)
2. Preset manifest needs a universe field
So the registry entry has something to record. For geektime, the universe is Star Trek: TNG. This should live in the preset metadata alongside name, version, description, agents.
3. squad doctor should catch this regression
Add at minimum:
- FAIL if
.squad/agents/contains any cast-eligible folder (notscribe/ralph/Rai) AND.squad/team.md## Memberstable has zero rows. Suggested fix message: "Runsquad preset apply <name>again, or runsquad hireto wire agents into the roster." - FAIL if
.squad/agents/contains cast-eligible folders AND.squad/casting/registry.jsonagentsmap is empty. Suggested fix message: "Casting registry is unpopulated — persistent name guarantees are not in effect." - WARN if
.squad/routing.mdcontains literal{Name}or{domainplaceholder tokens.
4. Idempotency
squad preset apply --force should re-wire the index files cleanly even if partial state already exists. Worth adding a test that runs apply twice and asserts the Members table doesn't grow duplicate rows.
Environment
squad v0.10.0- Windows 11 (
OS: Windows_NT) - Node.js v23.5.0
- Preset:
geektime - Non-git directory (
C:\temp\test-preset) - State backend:
local
Workaround
Manually populate the three files (about 30 lines of edits across team.md, casting/registry.json, routing.md) by reading each agent's charter.md. The coordinator's Init Mode Phase 2 logic in squad.agent.md already specifies the exact shape — the preset apply just isn't running it.
Activity
fix(presets): role-aware Status cell + non-colliding sentinel for syn…
fix(sdk): wire team.md/routing.md/casting state on \squad preset appl…
chore: promote v0.10.1 dev → main + v0.10 stabilisation blog post (#1313
chore: promote dev → main (v0.11.0) (#1422)