Repository navigation
fix(coordinator): stop on a bridge outage with a non-local backend - #2495
Merged
Merged
Conversation
In the #2487 scenario pass, with "stateBackend": "two-layer" and the squad_state server unable to start, the Claude coordinator recorded a decision by writing .squad/decisions.md directly, which that backend never reads. Item 16 said to stop for a non-local backend, but the coordinator had no way to know the backend with the bridge down. It now reads config.json, and when stateBackend is not local it stops, names the backend, and never writes state files as a workaround. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
🟡 Impact Analysis — PR #2495Risk tier: 🟡 MEDIUM 📊 Summary
🎯 Risk Factors
📦 Modules Affectedroot (3 files)
squad-sdk (1 file)
tests (1 file)
This report is generated automatically for every PR. See #733 for details. |
Contributor
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ✅ | Single commit | 1 commit — clean history |
| ✅ | 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 | 1 unresolved Copilot thread(s) — fix and resolve before merging |
| ✅ | CI passing | All checks passing |
Files Changed (5 files, +28 −2)
| File | +/− |
|---|---|
.changeset/backend-outage-stop.md |
+6 −0 |
CHANGELOG.md |
+1 −0 |
packages/squad-sdk/src/client/adapters/coordinator.ts |
+1 −1 |
plugins/squad/agents/squad.md |
+1 −1 |
test/coordinator-backend-outage.test.ts |
+19 −0 |
Total: +28 −2
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
The supported worktree backend alias is incorrectly treated as non-local during bridge outages, triggering an erroneous stop and misleading guidance about where state is stored.
1 open issue
What changed in this PR
This PR strengthens non-Copilot coordinator guidance for state-bridge outages, addressing the backend-isolation scenario in #2487.
Changes:
- Direct coordinators to check the configured backend, stop for non-local backends, and recommend
squad doctorinstead of writing state files directly. - Regenerate the Claude plugin while keeping its pinned version unchanged.
- Add wording checks across non-Copilot hosts and release notes. Live verification remains pending.
| File | Description |
|---|---|
test/coordinator-backend-outage.test.ts |
Checks outage guidance across hosts with a custom team folder. |
plugins/squad/agents/squad.md |
Includes the regenerated outage instructions. |
packages/squad-sdk/src/client/adapters/coordinator.ts |
Updates shared backend-outage guidance. |
CHANGELOG.md |
Documents the intended outage behavior. |
.changeset/backend-outage-stop.md |
Records SDK and CLI patch changes. |
Review effort: Balanced (dynamic)
| 14. **Fact Checker (verification and devil's advocate).** Spawn the Fact Checker to verify claims, URLs, packages, APIs and external references, rating each ✅ verified, ⚠️ partially verified / caveat, ❌ contradicted, 🔍 unverifiable/needs a source; findings are advisory and never implement or decide. On request ("challenge this plan", "devil's advocate") it steelmans the plan, lists assumptions, runs a pre-mortem, proposes alternatives and states the risk being accepted. Audit trail: \`${S}/fact-checker/audit-trail.md\`. | ||
| 15. **Ceremonies.** Read \`${S}/ceremonies.md\`. Before spawning work, run any ceremony whose trigger is \`before\` (e.g. design review) and after work completes run \`after\` ceremonies (e.g. retro), plus manual ones on request: spawn a synchronous facilitator (usually the Lead) with the ceremony definition, record outcomes via \`squad_decide\` (Scribe merges them), honor each ceremony's cooldown, and report the result. Details: \`${S}/templates/ceremony-reference.md\`. | ||
| 16. **Memory governance and state-backend handshake.** Before any state write, check \`squad_state_health\` once per session. Require its \`squad-state <version>\` line to match this coordinator's stamped Squad version, \`${COORDINATOR_SQUAD_VERSION}\`, and its \`Team squad dir:\` line to match the resolved \`${S}\`; an older/misdirected bridge is unavailable, not healthy. It also reports the backend (local, orphan, two-layer...). Use governed runtime tools only: \`squad_decide\` for decisions, \`squad_state_*\` for runtime state, and \`memory.*\` tools (classify/search/write/promote/delete/audit) when the MCP server exposes them. Never claim memory you cannot persist. If the bridge is unavailable for a non-local backend, stop and say so. Capture persistent user directives ("always...", "never...") via \`squad_decide\`, acknowledge them, and dispatch any implementation separately. | ||
| 16. **Memory governance and state-backend handshake.** Before any state write, check \`squad_state_health\` once per session. Require its \`squad-state <version>\` line to match this coordinator's stamped Squad version, \`${COORDINATOR_SQUAD_VERSION}\`, and its \`Team squad dir:\` line to match the resolved \`${S}\`; an older/misdirected bridge is unavailable, not healthy. It also reports the backend (local, orphan, two-layer...). Use governed runtime tools only: \`squad_decide\` for decisions, \`squad_state_*\` for runtime state, and \`memory.*\` tools (classify/search/write/promote/delete/audit) when the MCP server exposes them. Never claim memory you cannot persist. If the bridge is unavailable (the \`squad_state\` tools are missing, fail to start or error), read \`${S}/config.json\` (with Read; it is a small file): when its \`stateBackend\` is set to anything other than \`local\`, team state lives in that backend, not in the working tree, so stop and say so, naming the backend, and NEVER write \`${S}/decisions.md\`, the decisions inbox or other state files directly as a workaround; ask the user to fix the bridge (\`squad doctor\`). Capture persistent user directives ("always...", "never...") via \`squad_decide\`, acknowledge them, and dispatch any implementation separately. |
This was referenced Nov 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Found in the remaining #2487 scenarios.
Problem
The project had
"stateBackend": "two-layer"and an.mcp.jsonwhosesquad_stateserver couldn't start. Asked to "record a team decision", the Claude coordinator wrote straight into.squad/decisions.md, which a two-layer backend doesn't read, and reported success: "the squad_state MCP server was down this session, so I wrote the decision directly".Item 16 already said "if the bridge is unavailable for a non-local backend, stop and say so". But with the bridge down, the coordinator never learns which backend is configured:
squad_state_healthis what reports it.Fix
Item 16 now gives the coordinator a way to find out, and says what not to do:
squad_statetools are missing, fail to start or error, read.squad/config.json.stateBackendis anything other thanlocal, stop and say so, naming the backend.decisions.md, the decisions inbox or other state files directly as a workaround; point the user atsquad doctor.This applies to every non-Copilot host. The digest is 19.1–21.0 KB, under the 24 KB limit. Copilot is unchanged. The plugin is regenerated, still pinned to preview.4.
Tests
test/coordinator-backend-outage.test.tschecks the wording for every non-Copilot host, with a non-default squad folder name.claude -pstarted returning 403 from Cloudflare for every call, including a one-line "reply with OK". I'll re-run the scenario when that clears.Other #2487 scenarios run in the same pass
All three of these passed:
squad lockout reject, reassigned the fix to a different engineer (Kai, not the author Dallas), had Parker add tests, submitted it again, and Jordan approved.decisions.md, ran the tests and the review it listed, and handled a rejection along the way.decisions.mdrule ("every command supports--json") was followed by the engineer without being mentioned in the prompt.🤖 Generated with Claude Code