Skip to content

fix(coordinator): stop on a bridge outage with a non-local backend - #2495

Merged
bradygaster merged 1 commit into
devfrom
squad/backend-outage-stop
Nov 13, 2026
Merged

bradygaster merged 1 commit into
devfrom
squad/backend-outage-stop

Conversation

@bradygaster

Copy link
Copy Markdown
Collaborator

Found in the remaining #2487 scenarios.

Problem

The project had "stateBackend": "two-layer" and an .mcp.json whose squad_state server 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_health is what reports it.

Fix

Item 16 now gives the coordinator a way to find out, and says what not to do:

  • When the squad_state tools are missing, fail to start or error, read .squad/config.json.
  • If its stateBackend is anything other than local, stop and say so, naming the backend.
  • Never write decisions.md, the decisions inbox or other state files directly as a workaround; point the user at squad 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.ts checks the wording for every non-Copilot host, with a non-default squad folder name.
  • Not yet re-run live. During this work, claude -p started 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:

  • Reviewer rejection: the coordinator recorded the lockout with 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.
  • Restart continuity: a fresh session asked to "pick up where the team left off" found the TODO list the previous session left in decisions.md, ran the tests and the review it listed, and handled a rejection along the way.
  • Team decision precedence: a decisions.md rule ("every command supports --json") was followed by the engineer without being mentioned in the prompt.

🤖 Generated with Claude Code

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>
@bradygaster
bradygaster enabled auto-merge (squash) November 13, 2026 10:16
Copilot AI dynamic review requested due to automatic review settings November 13, 2026 10:16
@github-actions

Copy link
Copy Markdown
Contributor

🟡 Impact Analysis — PR #2495

Risk tier: 🟡 MEDIUM

📊 Summary

Metric Count
Files changed 5
Files added 2
Files modified 3
Files deleted 0
Modules touched 3

🎯 Risk Factors

  • 5 files changed (≤5 → LOW)
  • 3 modules touched (2-4 → MEDIUM)

📦 Modules Affected

root (3 files)
  • .changeset/backend-outage-stop.md
  • CHANGELOG.md
  • plugins/squad/agents/squad.md
squad-sdk (1 file)
  • packages/squad-sdk/src/client/adapters/coordinator.ts
tests (1 file)
  • test/coordinator-backend-outage.test.ts

This report is generated automatically for every PR. See #733 for details.

@github-actions

github-actions Bot commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor

🛫 PR Readiness Check

ℹ️ This comment updates on each push. Last checked: commit e437581

PR Scope: 📦🔧 Mixed (product + infrastructure)

⚠️ 2 item(s) to address before review

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.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 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 doctor instead 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.
@bradygaster
bradygaster merged commit 1a7ff45 into dev Nov 13, 2026
32 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants