diff --git a/cspell.json b/cspell.json index f32e9a10e..b9a9bb092 100644 --- a/cspell.json +++ b/cspell.json @@ -35,6 +35,7 @@ "booster", "bradygaster", "Breza", + "Bubu", "capcom", "chrislomonico", "Clemenza", @@ -129,6 +130,7 @@ "myrepo", "mysecret", "narratively", + "Noether", "nslookup", "OAuth", "orchestration", diff --git a/docs/src/content/docs/features/enterprise-platforms.md b/docs/src/content/docs/features/enterprise-platforms.md index 97e3598f7..6f872fa94 100644 --- a/docs/src/content/docs/features/enterprise-platforms.md +++ b/docs/src/content/docs/features/enterprise-platforms.md @@ -2,6 +2,8 @@ Squad supports Azure DevOps and Microsoft Planner in addition to GitHub. When your git remote points to Azure DevOps, Squad automatically detects the platform and adapts its commands. For work-item tracking, Squad also supports a hybrid model where code lives in one platform and tasks live in Microsoft Planner. +> **What "Azure DevOps support" means in Squad 2.0.** Platform **detection** (remote host or `config.platform`) and the CLI monitor loop β€” `squad triage` and `squad watch` β€” run on Azure DevOps through `az boards`. The **interactive Issues mode** inside a coordinator session ("show me the backlog", "work on item 42") is GitHub-only for now: the coordinator's Issues section is written for `gh`, and the Azure DevOps commands exist only as reference material in `.squad/templates/issue-lifecycle.md`, which the model has to apply by hand. Hosts do detect ADO from the remote and consult that template, so results are usable but not first-class. The `EXAMPLE-azure-devops` MCP server entry is seeded into Copilot's `.mcp.json` only. + ## Prerequisites 1. **Azure CLI** β€” Install from [https://aka.ms/install-az-cli](https://aka.ms/install-az-cli) diff --git a/docs/src/content/docs/features/gitlab-issues.md b/docs/src/content/docs/features/gitlab-issues.md index b982327e9..2021f1886 100644 --- a/docs/src/content/docs/features/gitlab-issues.md +++ b/docs/src/content/docs/features/gitlab-issues.md @@ -1,6 +1,6 @@ # GitLab Issues Mode -> **πŸ§ͺ Experimental.** GitLab Issues Mode is new. Commands, behavior, and integration details may change. [Feedback welcome.](https://github.com/bradygaster/squad/issues) +> **πŸ—ΊοΈ Planned, not shipped.** Squad 2.0 has no GitLab platform adapter: `PlatformType` is `github | azure-devops | planner`, `squad triage` / `squad watch` have no `glab` path, and neither the canonical coordinator nor the per-host digest contains a GitLab section. What follows describes the intended experience; today it only works if you ask the coordinator to use `glab` ad hoc and it improvises the flow described here. Track progress and vote in [issues](https://github.com/bradygaster/squad/issues). **Try this to connect to your backlog:** ``` diff --git a/docs/src/content/docs/reference/host-feature-matrix.md b/docs/src/content/docs/reference/host-feature-matrix.md new file mode 100644 index 000000000..34446328a --- /dev/null +++ b/docs/src/content/docs/reference/host-feature-matrix.md @@ -0,0 +1,1056 @@ +--- +title: Host Feature Matrix +description: Which Squad features work on which host (Copilot, Claude Code, Kiro, OpenCode, Cursor, Codex, Antigravity), what each depends on, and how each cell has been validated. +order: 16 +--- + +# Host Feature Matrix + + + +> πŸ”— Related: [Squad 2.0 Architecture](/squad/docs/concepts/squad-2-0-architecture/) Β· [Using Squad Across Clients](/squad/docs/scenarios/using-squad-across-clients/) Β· [Client Compatibility](/squad/docs/scenarios/client-compatibility/) + +Squad features fall into five dependency classes. Features that depend only on the `squad` CLI (class **a**) behave identically everywhere because the host is not involved. Everything else depends on what the host's coordinator file contains, whether the `squad_state` MCP bridge is reachable, and what the host runtime can do. The machine-readable source is `test-fixtures/spec/suite-v0.2/host-feature-matrix.json` (protocol `squad-protocol-v2.0-rc1`). + +## Dependency classes + +| Class | Depends on | +|-------|------------| +| **a** | squad CLI only (host-agnostic; the host is not involved) | +| **b** | coordinator-prompt behavior (the section must be present in the host's coordinator file or reachable on demand) | +| **c** | squad_state / memory.* MCP tools (state-mcp bridge reachable from the host) | +| **d** | host runtime capability (subagent spawn, background tasks, shell, file ops, sql, per-spawn model, MCP inheritance by subagents) | +| **e** | platform CLI or MCP availability in the host (gh / glab / az / ADO MCP / GitHub MCP) | + +## Legend + +Every cell has two independent values. **Capability** says what the host can do; **validation** says how that claim was established. Neither implies the other: a `supported` cell may be only `static-only`, and an `unsupported` cell can be `validated-test` (a test proves the gap). + +| Capability | Meaning | +|------------|---------| +| βœ… `supported` | The host can do this through the stated mechanism, with no known limitation. | +| ⚠️ `degraded` | The host does this partially: it works, but with the stated limitation (for example a synchronous fallback, an on-demand path, or a host runtime gap). | +| ❌ `unsupported` | The host cannot do this today β€” including every case where the coordinator section the feature relies on is absent from the host's projected digest. Stays unsupported until the section ships. | +| β€” `n/a` | Not applicable to this host (a Copilot-only surface or something that runs outside the host). | + +| Validation | Meaning | +|------------|---------| +| πŸ§ͺ `validated-test` | An automated test in this repository asserts the cell (see `evidence`; CLI/SDK tests are host-independent). For `unsupported` digest-gap cells this is the per-host `it.fails` that proves the section is absent. | +| πŸ–₯️ `validated-live` | A recorded headless run of the real host CLI against a real model passed on the reference machine (Claude Code and OpenCode only, 2026-10-22); the test-level evidence also applies. | +| πŸ“„ `static-only` | Only the projected/canonical text or the source was inspected; no automated or live evidence for this cell. | +| ❔ `untested` | Nothing beyond static reading, and no live attempt was made for this host. | +| β›” `blocked` | A live run was attempted for this host and could not complete for an external reason (`blockedReason`); confidence is the same as `untested`. | + +| Evidence entry | Meaning | +|----------------|---------| +| `validated-test:::` | Automated test (name `*` = the whole file). The title must appear literally in the file. | +| `validated-manual:lab:@` | A recorded live run (see the live run log) for this host and scenario. | +| `static-only` | Marker: the cell was (also) read statically. | + +Each matrix cell shows **capability validation** (for example `βœ… πŸ§ͺ` = supported, covered by an automated test; `❌ πŸ§ͺ` = unsupported, proven by an expected-failure test; `βœ… πŸ“„` = supported, statically inspected only; `βœ… β›”` = supported on paper, the live attempt for this host was blocked). + +## Hosts + +| Host | CLI | Coordinator file | MCP config | Subagents | Background | Per-spawn model | Subagents inherit MCP | +|------|-----|------------------|------------|-----------|------------|-----------------|-----------------------| +| **GitHub Copilot (CLI / app / VS Code)** (`copilot`) | `copilot` | .github/agents/squad.agent.md (canonical) | .mcp.json | yes | yes | yes | yes | +| **Claude Code** (`claude`) | `claude` | .claude/agents/squad.md (digest) + CLAUDE.md block | .mcp.json | yes | no | no | yes | +| **Kiro CLI** (`kiro`) | `kiro-cli` | .kiro/agents/squad.json + .kiro/steering/squad.md (manual) | .kiro/settings/mcp.json | yes | no | no | yes | +| **OpenCode** (`opencode`) | `opencode` | .opencode/agents/squad.md (primary) | opencode.json (mcp.squad_state) | yes | yes | no | yes | +| **Cursor** (`cursor`) | `cursor-agent` (installed; the live smoke run was blocked by a usage limit (see live run log), so cells without a dedicated test are untested) | .cursor/rules/squad.mdc (alwaysApply: false) + .cursor/agents/squad.md | .cursor/mcp.json | yes | no | no | yes | +| **OpenAI Codex** (`codex`) | `codex` (not on the reference machine β†’ static-only) | .codex/agents/squad.toml (developer_instructions) + AGENTS.md pointer | .codex/config.toml (mcp_servers.squad_state) | yes | no | no | yes | +| **Google Antigravity** (`antigravity`) | `agy` | .agents/agents/squad.md + GEMINI.md block | agent frontmatter mcpServers (or `agy mcp add`) | yes | no | no | no | + +## Summary + +Capability counts and validation counts are independent breakdowns of the same cells (each row sums to the feature count twice). + +| Host | βœ… supported | ⚠️ degraded | ❌ unsupported | β€” n/a | πŸ–₯️ validated-live | πŸ§ͺ validated-test | πŸ“„ static-only | ❔ untested | β›” blocked | of which expected-failure gaps | +|------|-------------|-------------|----------------|-------|-------------------|-------------------|----------------|------------|------------|--------------------------------| +| `copilot` | 44 | 0 | 7 | 0 | 0 | 49 | 2 | 0 | 0 | 7 | +| `claude` | 39 | 2 | 7 | 3 | 18 | 30 | 3 | 0 | 0 | 7 | +| `kiro` | 39 | 2 | 7 | 3 | 0 | 47 | 3 | 0 | 1 | 7 | +| `opencode` | 40 | 1 | 7 | 3 | 18 | 30 | 3 | 0 | 0 | 7 | +| `cursor` | 39 | 2 | 7 | 3 | 0 | 47 | 3 | 0 | 1 | 7 | +| `codex` | 39 | 2 | 7 | 3 | 0 | 47 | 3 | 1 | 0 | 7 | +| `antigravity` | 38 | 3 | 7 | 3 | 0 | 47 | 3 | 0 | 1 | 7 | + +## Expected failures (`it.fails`) + +These digest gaps are pinned as expected failures, one test per host and gap: the `[]` test turns red the moment a stack adds the section for that host. Until then the cell is **unsupported** for that host (validated by the failing test), never degraded or supported. + +| Feature | Test (title; each generated test appends the host as `[]`) | Hosts | Meaning | +|---------|-----------------------------|-------|---------| +| [monorepo-team-root](#monorepo-team-root) | `test/clients.test.ts::digest gap (expected until the stack adds it): team-root resolution (teamRoot / stateLocation / TEAM_ROOT)` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | +| [dual-root-remote-mode](#dual-root-remote-mode) | `test/clients.test.ts::digest gap (expected until the stack adds it): team-root resolution (teamRoot / stateLocation / TEAM_ROOT)` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | +| [upstream-inheritance](#upstream-inheritance) | `test/clients.test.ts::digest gap (expected until the stack adds it): upstream inheritance (upstream.json)` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | +| [azure-devops](#azure-devops) | `test/clients.test.ts::digest gap (expected until the stack adds it): Azure DevOps issue tracking (az boards / ADO)` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | +| [gitlab-issues](#gitlab-issues) | `test/clients.test.ts::digest gap (expected until the stack adds it): GitLab issue tracking (glab)` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | +| [model-selection](#model-selection) | `test/clients.test.ts::digest gap (expected until the stack adds it): per-agent model / reasoning / context-tier selection` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | +| [marketplace-plugins](#marketplace-plugins) | `test/clients.test.ts::digest gap (expected until the stack adds it): plugin marketplace browse on cast` (it.fails, per host) | `copilot` `claude` `kiro` `opencode` `cursor` `codex` `antigravity` | The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then. | + +## Known limitations of this evidence + +- Capability and validation are separate axes: a `supported` cell may be only `static-only`, and an `unsupported` digest-gap cell is `validated-test` because an `it.fails` proves the gap. Read both columns. +- Expected failures are pinned per host and per gap (one `it.fails` per ` []` pair); a section landing for one host turns exactly that host's test red. Those cells are `unsupported`, never `degraded`. +- Live evidence exists for Claude Code and OpenCode only (reference machine, 2026-10-22). Kiro, Codex, Antigravity and Cursor have no passing live run: their cells are `validated-test` only through host-independent tests, otherwise `static-only`, `untested` or `blocked`. +- The opt-in headless coordinator tests (`SQUAD_REAL_MODEL_TESTS=1`) verify the MCP bridge through a tee'd `squad state-mcp` transcript (a successful `tools/call` of `squad_state_read` with `key: "team.md"`), not by matching stdout. No other cell claims bridge-level verification. + +## Matrix + +### Core + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Init Mode & casting (`squad init`, `squad cast --name`, casting registry)](#init-mode-casting) | a, b | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Work routing by ownership (`routing.md`, one accountable owner, named requests)](#routing-ownership) | b | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Response modes (Direct / Lightweight / Standard / Full) + "feels heard" acknowledgement](#response-modes) | b | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Model / reasoning-effort / context-tier selection per spawn](#model-selection) | b, d | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | +| [Parallel fan-out of independent specialists](#parallel-fanout) | b, d | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Background agents (Scribe/Rai run non-blocking)](#background-agents) | d | βœ… πŸ§ͺ | ⚠️ πŸ–₯️ | ⚠️ πŸ§ͺ | βœ… πŸ–₯️ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | +| [Skills (5 roots, precedence, untrusted-data rule)](#skills-precedence) | b | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Standalone install (no npm; `squad.exe state-mcp` launch spec)](#standalone-install) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [VS Code (`runSubagent`, settings default agent)](#vscode) | d | βœ… πŸ§ͺ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | +| [SDK-first mode (`squad.config.ts`, `squad build`, `squad migrate`)](#sdk-first-mode) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Maintenance CLIs (`squad doctor`, `squad health`, `squad nap`, `squad upgrade`)](#doctor-health-nap) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Process hygiene (never kill by image name; PID-only)](#process-hygiene) | b | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | + +### Memory + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Scribe, decisions drop-box, agent history, orchestration log](#scribe-decisions-history) | b, c | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Directive capture ("always…/never…" β†’ `squad_decide`)](#directive-capture) | b, c | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Memory governance (`memory.*` tools, classes, promote/audit)](#memory-governance) | c | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [State backends (`local` / `orphan` / `two-layer`) + handshake](#state-backends) | a, c, b | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | + +### Quality + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Reviewer rejection protocol & strict author lockout](#reviewer-lockout) | b | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Rai β€” Responsible-AI reviewer (🟒/🟑/πŸ”΄)](#rai) | b, d | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Fact Checker β€” verification & devil's advocate](#fact-checker) | b | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | + +### Advanced + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Ceremonies (before/after/manual, cooldowns)](#ceremonies) | b, c | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Human team members (never spawned; routed as requests)](#human-members) | b | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [PRD mode (decompose β†’ approve β†’ dependency-aware dispatch)](#prd-mode) | b | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Git worktrees & worktree mode (issue worktrees, `WORKTREE_PATH`)](#git-worktrees) | a, b, d | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Export / import (`squad export`, `squad import`, team portability)](#export-import) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Marketplace & plugins (`squad plugin marketplace …`, skill install on cast)](#marketplace-plugins) | a, b | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | +| [MCP integration (user MCP servers discovered; MCP β†’ CLI fallback)](#mcp-integration) | b, d | βœ… πŸ“„ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Squad RC / `squad start` (remote control bridge, tunnels)](#squad-rc-start) | a, d | βœ… πŸ§ͺ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | + +### GitHub + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [@copilot coding agent member (`squad copilot`, GitHub assignment)](#copilot-coding-agent) | a, b, e | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Ralph β€” interactive work monitor ("Ralph, go")](#ralph-coordinator-loop) | b, e | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Ralph CLI (`squad triage` / `watch` / `loop` --execute)](#ralph-cli-triage-watch) | a, e (host-independent) | βœ… πŸ§ͺ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | ⚠️ πŸ§ͺ | +| [GitHub Issues mode (connect, list, route, branch β†’ PR β†’ merge)](#github-issues-mode) | b, e | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Labels & triage (`squad` / `squad:` taxonomy)](#labels-triage) | a, b, e | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Project boards (`squad triage --board`)](#project-boards) | a, e (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [GitHub Agentic Workflows (gh-aw) integration](#gh-aw) | e | βœ… πŸ§ͺ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | β€” πŸ“„ | + +### Platforms + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [GitLab Issues mode (experimental, `glab`)](#gitlab-issues) | b, e | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | +| [Azure DevOps platform (work items, PRs, `az boards`, ADO MCP)](#azure-devops) | a, b, e | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | + +### Multi-squad + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Upstream inheritance (`squad upstream add\|sync`, inherited skills/decisions/wisdom/routing)](#upstream-inheritance) | a, b | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | +| [Multiple squads / cross-squad (`squad registry\|discover\|delegate`, cross-squad skills)](#cross-squad-registry) | a, b, e | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [SubSquads / workstreams (`squad subsquads`, multi-Codespace)](#subsquads) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Monorepo / team-root resolution (`--team-root`, `SQUAD_TEAM_ROOT`, launch from a subfolder)](#monorepo-team-root) | a, b, c, d | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | +| [Dual-root remote mode (`squad init --mode remote`, `link`, `externalize` / `internalize`)](#dual-root-remote-mode) | a, b, c | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | ❌ πŸ§ͺ | + +### Infrastructure + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Storage provider abstraction (FS / SQLite / external state)](#storage-provider) | a, c (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Notifications (`watch --notify-level`, Teams/email monitors)](#notifications) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Enterprise platforms (ADO + Planner work items, Teams/ADO discussions)](#enterprise-platforms) | a, e (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Distributed mesh, capability routing, rate limiting, KEDA autoscaling](#distributed-mesh) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Aspire dashboard / OTel observability (`squad aspire`)](#aspire-dashboard) | a (host-independent) | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | + +### Squad 2.0 + +| Feature | Deps | `copilot` | `claude` | `kiro` | `opencode` | `cursor` | `codex` | `antigravity` | +|---------|------|---|---|---|---|---|---|---| +| [Squad 2.0 `--client` projection (coordinator file + MCP config per host, rollback)](#client-projection) | a, d | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [`squad_state` MCP bridge reachable from the host (stdio, host-prefixed tool names)](#squad-state-mcp-bridge) | c, d | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ–₯️ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Capability negotiation (client ∩ backend ∩ policy)](#capability-negotiation) | c | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Experimental conversation backend (`squad_backend_*`, durable-http, approvals, resume)](#experimental-backend) | c | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | βœ… πŸ§ͺ | +| [Specialists (subagents) can reach `squad_state` tools themselves](#subagent-mcp-inheritance) | d | βœ… πŸ“„ | βœ… πŸ–₯️ | βœ… β›” | βœ… πŸ–₯️ | βœ… β›” | βœ… ❔ | ⚠️ β›” | + +## Per-feature detail + +### init-mode-casting + +**Init Mode & casting (`squad init`, `squad cast --name`, casting registry)** + +Depends on: **a, b** Β· docs: [features/team-setup](/squad/docs/features/team-setup/) Β· [concepts/your-team](/squad/docs/concepts/your-team/) Β· canonical sections: `Init Mode`, `Casting & Persistent Naming` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. _Live: cast 4 members via `squad cast --name` (registry pair valid); ignored the requested descriptive universe and used Apollo 13 names._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`validated-manual:lab:init-mode@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. _Live: cast 4 members via `squad cast --name` with descriptive names; registry pair valid._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`validated-manual:lab:init-mode@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry`
`validated-test:test/cli/init.test.ts::*`
`static-only` | + +### routing-ownership + +**Work routing by ownership (`routing.md`, one accountable owner, named requests)** + +Depends on: **b** Β· docs: [features/routing](/squad/docs/features/routing/) Β· canonical sections: `Routing`, `Scope Control` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:smoke-roster@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:smoke-roster@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### response-modes + +**Response modes (Direct / Lightweight / Standard / Full) + "feels heard" acknowledgement** + +Depends on: **b** Β· docs: [features/response-modes](/squad/docs/features/response-modes/) Β· canonical sections: `Response Mode Selection`, `Acknowledge Immediately β€” "Feels Heard"` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:smoke-roster@2026-10-22`
`validated-manual:lab:ralph-no-repo@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:smoke-roster@2026-10-22`
`validated-manual:lab:ralph-no-repo@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§10 carries all four modes and the acknowledge-then-spawn rule. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### model-selection + +**Model / reasoning-effort / context-tier selection per spawn** + +Depends on: **b, d** Β· docs: [features/model-selection](/squad/docs/features/model-selection/) Β· [scenarios/switching-models](/squad/docs/scenarios/switching-models/) Β· canonical sections: `Per-Agent Model Selection`, `Per-Agent Reasoning Effort`, `Per-Agent Context Tier` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Canonical Β§Model Selection + `task` tool `model`/`reasoning_effort`/`context_tier` params; `.squad/config.json` overrides. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The CLI/SDK side works, but the projected digest carries no section for it, so the coordinator is not told about it on this host. Unsupported on this host until the section ships._ | `validated-test:test/model-selector-policy.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | `Task` has no per-call model; only subagent-definition `model:` frontmatter. Digest lacks the model-selection section. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited. _Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Model is set per agent in `opencode.json` (`agent.squad.model`), not per `task` call; reasoning/context tiers unsupported. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited. _Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited. _Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited. _Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### parallel-fanout + +**Parallel fan-out of independent specialists** + +Depends on: **b, d** Β· docs: [features/parallel-execution](/squad/docs/features/parallel-execution/) Β· [concepts/parallel-work](/squad/docs/concepts/parallel-work/) Β· canonical sections: `Team Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-manual:lab:parallel-fanout@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-manual:lab:parallel-fanout@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`static-only` | + +### background-agents + +**Background agents (Scribe/Rai run non-blocking)** + +Depends on: **d** Β· docs: [features/parallel-execution](/squad/docs/features/parallel-execution/) Β· canonical sections: `Shared Decision Architecture β€” Drop-Box Pattern` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `background-runs` token; `task` mode=background / `read_agent`. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts` | +| `claude` | ⚠️ degraded | πŸ–₯️ validated-live | No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background. _F7: Claude Code 2.1.296 actually ran the two specialist `Agent` spawns in the background (`subagent_stats.started_in_background`); the `background-runs` token is absent from the matrix, so Squad under-declares Claude here._ | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-manual:lab:parallel-fanout@2026-10-22` | +| `kiro` | ⚠️ degraded | πŸ§ͺ validated-test | No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | `background-runs` token declared; `task` subagents run as child sessions. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-manual:lab:parallel-fanout@2026-10-22` | +| `cursor` | ⚠️ degraded | πŸ§ͺ validated-test | No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts` | +| `codex` | ⚠️ degraded | πŸ§ͺ validated-test | No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts` | +| `antigravity` | ⚠️ degraded | πŸ§ͺ validated-test | No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts` | + +### scribe-decisions-history + +**Scribe, decisions drop-box, agent history, orchestration log** + +Depends on: **b, c** Β· docs: [features/memory](/squad/docs/features/memory/) Β· [concepts/memory-and-knowledge](/squad/docs/concepts/memory-and-knowledge/) Β· canonical sections: `Shared Decision Architecture β€” Drop-Box Pattern`, `Built-in Support Agents` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-manual:lab:parallel-fanout@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-manual:lab:parallel-fanout@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`static-only` | + +### directive-capture + +**Directive capture ("always…/never…" β†’ `squad_decide`)** + +Depends on: **b, c** Β· docs: [features/directives](/squad/docs/features/directives/) Β· canonical sections: `Directive Capture` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:directive-capture@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:directive-capture@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### memory-governance + +**Memory governance (`memory.*` tools, classes, promote/audit)** + +Depends on: **c** Β· docs: [features/memory](/squad/docs/features/memory/) Β· canonical sections: `Memory Governance Tools` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`validated-manual:lab:state-orphan@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`validated-manual:lab:state-orphan@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | `memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/memory-governance.test.ts::*`
`static-only` | + +### state-backends + +**State backends (`local` / `orphan` / `two-layer`) + handshake** + +Depends on: **a, c, b** Β· docs: [features/state-backends](/squad/docs/features/state-backends/) Β· [reference/state-backend-selection](/squad/docs/reference/state-backend-selection/) Β· canonical sections: `State & Team Root Resolution (before mode check)`, `Memory Governance Tools` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. _F6: `squad_state_health` answered "State backend storage: StateBackendStorageAdapter" instead of the backend name the digest promises._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-manual:lab:state-orphan@2026-10-22`
`validated-manual:lab:state-twolayer@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. _F6: `squad_state_health` answered "State backend storage: StateBackendStorageAdapter" instead of the backend name the digest promises._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-manual:lab:state-orphan@2026-10-22`
`validated-manual:lab:state-twolayer@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | `squad init\|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend`
`validated-test:test/state-backend.test.ts::*`
`validated-test:test/upgrade-state-backend.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree` | + +### skills-precedence + +**Skills (5 roots, precedence, untrusted-data rule)** + +Depends on: **b** Β· docs: [features/skills](/squad/docs/features/skills/) Β· canonical sections: `Team Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`validated-manual:lab:skills-precedence@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`validated-manual:lab:skills-precedence@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/skills.test.ts::*`
`static-only` | + +### reviewer-lockout + +**Reviewer rejection protocol & strict author lockout** + +Depends on: **b** Β· docs: [features/reviewer-protocol](/squad/docs/features/reviewer-protocol/) Β· canonical sections: `Reviewer Rejection Protocol` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:reviewer-lockout@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:reviewer-lockout@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§12: REJECT locks out the author; revision reassigned; re-review required. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### rai + +**Rai β€” Responsible-AI reviewer (🟒/🟑/πŸ”΄)** + +Depends on: **b, d** Β· docs: [features/reviewer-protocol](/squad/docs/features/reviewer-protocol/) Β· canonical sections: `Rai β€” RAI Reviewer` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Canonical Β§Rai; background by default. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents). | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents). _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Digest Β§13; background capable. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents). _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents). _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents). _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### fact-checker + +**Fact Checker β€” verification & devil's advocate** + +Depends on: **b** Β· docs: [features/reviewer-protocol](/squad/docs/features/reviewer-protocol/) Β· canonical sections: `Fact Checker β€” Verification & Devil's Advocate` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### ceremonies + +**Ceremonies (before/after/manual, cooldowns)** + +Depends on: **b, c** Β· docs: [features/ceremonies](/squad/docs/features/ceremonies/) Β· canonical sections: `Ceremonies` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### human-members + +**Human team members (never spawned; routed as requests)** + +Depends on: **b** Β· docs: [features/human-team-members](/squad/docs/features/human-team-members/) Β· [scenarios/team-of-humans](/squad/docs/scenarios/team-of-humans/) Β· canonical sections: `Team Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§21. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### copilot-coding-agent + +**@copilot coding agent member (`squad copilot`, GitHub assignment)** + +Depends on: **a, b, e** Β· docs: [features/copilot-coding-agent](/squad/docs/features/copilot-coding-agent/) Β· canonical sections: `Copilot Coding Agent Member` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/team-capabilities-lifecycle.test.ts::*`
`static-only` | + +### ralph-coordinator-loop + +**Ralph β€” interactive work monitor ("Ralph, go")** + +Depends on: **b, e** Β· docs: [features/ralph](/squad/docs/features/ralph/) Β· canonical sections: `Ralph β€” Work Monitor` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:ralph-no-repo@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:ralph-no-repo@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### ralph-cli-triage-watch + +**Ralph CLI (`squad triage` / `watch` / `loop` --execute)** + +Depends on: **a, e** (host-independent) Β· docs: [features/ralph](/squad/docs/features/ralph/) Β· [features/labels](/squad/docs/features/labels/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Default `agentCmd` is the Copilot CLI (`copilot -p …`). | `validated-test:test/ralph-triage.test.ts::*`
`validated-test:test/ralph-monitor.test.ts::*`
`validated-test:test/watch-fleet-dispatch.test.ts::*` | +| `claude` | ⚠️ degraded | πŸ§ͺ validated-test | Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd " … {prompt}"`) is configured; no built-in preset for this host. | `validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `kiro` | ⚠️ degraded | πŸ§ͺ validated-test | Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd " … {prompt}"`) is configured; no built-in preset for this host. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `opencode` | ⚠️ degraded | πŸ§ͺ validated-test | Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd " … {prompt}"`) is configured; no built-in preset for this host. | `validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `cursor` | ⚠️ degraded | πŸ§ͺ validated-test | Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd " … {prompt}"`) is configured; no built-in preset for this host. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `codex` | ⚠️ degraded | πŸ§ͺ validated-test | Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd " … {prompt}"`) is configured; no built-in preset for this host. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `antigravity` | ⚠️ degraded | πŸ§ͺ validated-test | Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd " … {prompt}"`) is configured; no built-in preset for this host. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/ralph-triage.test.ts::*`
`static-only` | + +### prd-mode + +**PRD mode (decompose β†’ approve β†’ dependency-aware dispatch)** + +Depends on: **b** Β· docs: [features/prd-mode](/squad/docs/features/prd-mode/) Β· canonical sections: `PRD Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§19; `prd-intake.md` template on demand. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### github-issues-mode + +**GitHub Issues mode (connect, list, route, branch β†’ PR β†’ merge)** + +Depends on: **b, e** Β· docs: [features/github-issues](/squad/docs/features/github-issues/) Β· [concepts/github-workflow](/squad/docs/concepts/github-workflow/) Β· [scenarios/issue-driven-dev](/squad/docs/scenarios/issue-driven-dev/) Β· canonical sections: `GitHub Issues Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:github-issues-readonly@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-manual:lab:github-issues-readonly@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### labels-triage + +**Labels & triage (`squad` / `squad:` taxonomy)** + +Depends on: **a, b, e** Β· docs: [features/labels](/squad/docs/features/labels/) Β· canonical sections: `GitHub Issues Mode`, `Ralph β€” Work Monitor` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`validated-manual:lab:github-issues-readonly@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`validated-manual:lab:github-issues-readonly@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/ralph-triage.test.ts::*`
`static-only` | + +### project-boards + +**Project boards (`squad triage --board`)** + +Depends on: **a, e** (host-independent) Β· docs: [features/project-boards](/squad/docs/features/project-boards/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | CLI capability, GitHub Projects via `gh`; the local host is not involved. | `validated-test:test/ralph-board.test.ts::*` | + +### gitlab-issues + +**GitLab Issues mode (experimental, `glab`)** + +Depends on: **b, e** Β· docs: [features/gitlab-issues](/squad/docs/features/gitlab-issues/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage\|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`. _Finding F2. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### azure-devops + +**Azure DevOps platform (work items, PRs, `az boards`, ADO MCP)** + +Depends on: **a, b, e** Β· docs: [features/enterprise-platforms](/squad/docs/features/enterprise-platforms/) Β· canonical sections: `GitHub Issues Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | `squad triage\|watch` auto-detect ADO from the remote (or `config.platform: azure-devops`) and use `az`; `squad upgrade` seeds an `EXAMPLE-azure-devops` MCP server in `.mcp.json`. The coordinator section is GitHub-only (`gh`); ADO commands exist only in `issue-lifecycle.md`. _Finding F3: interactive Issues mode has no ADO branch in the prompt. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand. _Finding F3. Live: detected ADO from the remote, read `issue-lifecycle.md`, proposed `az boards` commands, noted the template has no backlog-list command. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-manual:lab:ado-platform@2026-10-22`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand. _Finding F3. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand. _Finding F3. Live: detected ADO from the remote, read `issue-lifecycle.md`, proposed `az boards` commands, noted the template has no backlog-list command. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-manual:lab:ado-platform@2026-10-22`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand. _Finding F3. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand. _Finding F3. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand. _Finding F3. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### upstream-inheritance + +**Upstream inheritance (`squad upstream add|sync`, inherited skills/decisions/wisdom/routing)** + +Depends on: **a, b** Β· docs: [features/upstream-inheritance](/squad/docs/features/upstream-inheritance/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. Live (Claude): found both upstream decision and skill, but only because the prompt pointed at `upstream.json`. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-manual:lab:upstream@2026-10-22`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. Live (OpenCode, partial): found the upstream decision but missed `.copilot/skills/org-logging` (outside the `.squad/` the upstream points at), which `resolveUpstreams()` would have returned. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-manual:lab:upstream@2026-10-22`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it). _Finding F1: docs promise "coordinator reads upstreams at session start" but no prompt/CLI path implements it on any host. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/upstream.test.ts::*`
`validated-test:test/upstream-e2e.test.ts::*`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### cross-squad-registry + +**Multiple squads / cross-squad (`squad registry|discover|delegate`, cross-squad skills)** + +Depends on: **a, b, e** Β· docs: [scenarios/multiple-squads](/squad/docs/scenarios/multiple-squads/) Β· canonical sections: `Team Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`validated-manual:lab:cross-squad@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`validated-manual:lab:cross-squad@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`). _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`validated-test:test/cross-squad-registry.test.ts::*`
`validated-test:test/cross-squad.test.ts::*`
`static-only` | + +### subsquads + +**SubSquads / workstreams (`squad subsquads`, multi-Codespace)** + +Depends on: **a** (host-independent) Β· docs: [scenarios/multi-codespace](/squad/docs/scenarios/multi-codespace/) Β· [scenarios/scaling-workstreams](/squad/docs/scenarios/scaling-workstreams/) Β· [features/streams](/squad/docs/features/streams/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | CLI + watch discovery; host not involved. | `validated-test:test/watch-subsquad-discovery.test.ts::*` | + +### monorepo-team-root + +**Monorepo / team-root resolution (`--team-root`, `SQUAD_TEAM_ROOT`, launch from a subfolder)** + +Depends on: **a, b, c, d** Β· docs: [scenarios/monorepo](/squad/docs/scenarios/monorepo/) Β· [features/worktrees](/squad/docs/features/worktrees/) Β· canonical sections: `State & Team Root Resolution (before mode check)` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI honours `--team-root`/`SQUAD_TEAM_ROOT`; state-mcp walks up from cwd (`findSquadDir`); canonical Β§State & Team Root Resolution + `worktree-reference.md` resolve `TEAM_ROOT` and pass it to every spawn. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | Claude discovers `.claude/agents/squad.md` and `.mcp.json` from a package subfolder; state-mcp walks up to the root `.squad/`. Headless (`-p`) runs need `--mcp-config /.mcp.json` or a prior per-project approval (F5). _Validate per host: does the host find root-level projections from a subfolder cwd? Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-manual:lab:mono-subfolder@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/squad-20-host-feature-matrix.test.ts::claude lists the root .mcp.json squad_state server from packages/api`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all. _Validate per host: does the host find root-level projections from a subfolder cwd? Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | OpenCode resolves `opencode.json` (agent + MCP) from the repo root when launched in a package subfolder; state-mcp walks up to the root `.squad/`. _Validate per host: does the host find root-level projections from a subfolder cwd? Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-manual:lab:mono-subfolder@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/squad-20-host-feature-matrix.test.ts::opencode resolves the squad primary agent and the squad_state MCP entry from packages/api`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all. _Validate per host: does the host find root-level projections from a subfolder cwd? Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all. _Validate per host: does the host find root-level projections from a subfolder cwd? No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all. _Validate per host: does the host find root-level projections from a subfolder cwd? Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### dual-root-remote-mode + +**Dual-root remote mode (`squad init --mode remote`, `link`, `externalize` / `internalize`)** + +Depends on: **a, b, c** Β· docs: [features/dual-mode-deployment](/squad/docs/features/dual-mode-deployment/) Β· [scenarios/team-state-storage](/squad/docs/scenarios/team-state-storage/) Β· canonical sections: `State & Team Root Resolution (before mode check)` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI writes `config.json.teamRoot`; state-mcp resolves `mode: remote`; canonical step 3 loads `team.md` from the team root. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | The state bridge follows `config.json.teamRoot`, so the host coordinator read the team-root roster via `squad_state_read` and did not enter Init Mode, even though the digest has no team-root section. _Live: roster served from `..\base`; no casting attempted. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-manual:lab:satellite-remote@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator. _Finding F4 candidate β€” validate. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | The state bridge follows `config.json.teamRoot`, so the host coordinator read the team-root roster via `squad_state_read` and did not enter Init Mode, even though the digest has no team-root section. _Live: roster served from `..\base`; no casting attempted. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-manual:lab:satellite-remote@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator. _Finding F4 candidate β€” validate. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator. _Finding F4 candidate β€” validate. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator. _Finding F4 candidate β€” validate. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/resolution.test.ts::*`
`validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)`
`validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### git-worktrees + +**Git worktrees & worktree mode (issue worktrees, `WORKTREE_PATH`)** + +Depends on: **a, b, d** Β· docs: [features/worktrees](/squad/docs/features/worktrees/) Β· canonical sections: `Team Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`validated-manual:lab:worktree-spawn@2026-10-22` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`validated-manual:lab:worktree-spawn@2026-10-22` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator Ralph mode`
`validated-test:test/worktree.test.ts::*`
`static-only` | + +### export-import + +**Export / import (`squad export`, `squad import`, team portability)** + +Depends on: **a** (host-independent) Β· docs: [features/export-import](/squad/docs/features/export-import/) Β· [scenarios/team-portability](/squad/docs/scenarios/team-portability/) Β· [concepts/portability](/squad/docs/concepts/portability/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; portable `clients[]` hygiene strips host secrets. | `validated-test:test/cli/export-import.test.ts::*`
`validated-test:test/clients.test.ts::portable clients[] hygiene` | + +### storage-provider + +**Storage provider abstraction (FS / SQLite / external state)** + +Depends on: **a, c** (host-independent) Β· docs: [features/storage-provider](/squad/docs/features/storage-provider/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | SDK/CLI layer under state-mcp; host not involved. | `validated-test:test/state-backend.test.ts::*` | + +### notifications + +**Notifications (`watch --notify-level`, Teams/email monitors)** + +Depends on: **a** (host-independent) Β· docs: [features/notifications](/squad/docs/features/notifications/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | CLI watch capability. | `validated-test:test/watch-notify-level.test.ts::*` | + +### marketplace-plugins + +**Marketplace & plugins (`squad plugin marketplace …`, skill install on cast)** + +Depends on: **a, b** Β· docs: [features/marketplace](/squad/docs/features/marketplace/) Β· [features/plugins](/squad/docs/features/plugins/) Β· canonical sections: `Team Mode` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI + canonical "check plugin marketplaces when adding a member" step. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The CLI/SDK side works, but the projected digest carries no section for it, so the coordinator is not told about it on this host. Unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `claude` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI works; the digest Init/cast flow does not include the marketplace-browse step. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `kiro` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI works; the digest Init/cast flow does not include the marketplace-browse step. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `opencode` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI works; the digest Init/cast flow does not include the marketplace-browse step. _Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `cursor` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI works; the digest Init/cast flow does not include the marketplace-browse step. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `codex` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI works; the digest Init/cast flow does not include the marketplace-browse step. _No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | +| `antigravity` | ❌ unsupported | πŸ§ͺ validated-test (expected failure) | CLI works; the digest Init/cast flow does not include the marketplace-browse step. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships._ | `validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix`
`static-only` | + +### mcp-integration + +**MCP integration (user MCP servers discovered; MCP β†’ CLI fallback)** + +Depends on: **b, d** Β· docs: [features/mcp](/squad/docs/features/mcp/) Β· canonical sections: `MCP Integration` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ“„ static-only | Canonical Β§MCP Integration with tool-prefix discovery and `gh`/`az` fallbacks; `.mcp.json`. | `static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | + +### standalone-install + +**Standalone install (no npm; `squad.exe state-mcp` launch spec)** + +Depends on: **a** (host-independent) Β· docs: [features/standalone-install](/squad/docs/features/standalone-install/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | `mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection. | `validated-test:test/cli/upgrade.test.ts::*` | + +### vscode + +**VS Code (`runSubagent`, settings default agent)** + +Depends on: **d** Β· docs: [features/vscode](/squad/docs/features/vscode/) Β· canonical sections: `Client Compatibility` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Canonical Β§Client Compatibility micro-playbook; `squad init` writes `.vscode/settings.json`. | `validated-test:test/cli/init.test.ts::*`
`static-only` | +| `claude` | β€” n/a | πŸ“„ static-only | Copilot-specific surface. | `static-only` | +| `kiro` | β€” n/a | πŸ“„ static-only | Copilot-specific surface. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `static-only` | +| `opencode` | β€” n/a | πŸ“„ static-only | Copilot-specific surface. | `static-only` | +| `cursor` | β€” n/a | πŸ“„ static-only | Copilot-specific surface. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `static-only` | +| `codex` | β€” n/a | πŸ“„ static-only | Copilot-specific surface. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `static-only` | +| `antigravity` | β€” n/a | πŸ“„ static-only | Copilot-specific surface. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `static-only` | + +### squad-rc-start + +**Squad RC / `squad start` (remote control bridge, tunnels)** + +Depends on: **a, d** Β· docs: [features/squad-rc](/squad/docs/features/squad-rc/) Β· [scenarios/remote-qa](/squad/docs/scenarios/remote-qa/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `squad start\|rc` wrap the Copilot CLI with phone/browser access. | `validated-test:test/cli/rc.test.ts::*`
`static-only` | +| `claude` | β€” n/a | πŸ“„ static-only | Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped. | `static-only` | +| `kiro` | β€” n/a | πŸ“„ static-only | Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `static-only` | +| `opencode` | β€” n/a | πŸ“„ static-only | Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped. | `static-only` | +| `cursor` | β€” n/a | πŸ“„ static-only | Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `static-only` | +| `codex` | β€” n/a | πŸ“„ static-only | Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `static-only` | +| `antigravity` | β€” n/a | πŸ“„ static-only | Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `static-only` | + +### enterprise-platforms + +**Enterprise platforms (ADO + Planner work items, Teams/ADO discussions)** + +Depends on: **a, e** (host-independent) Β· docs: [features/enterprise-platforms](/squad/docs/features/enterprise-platforms/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage\|watch`. | `validated-test:test/platform-adapter.test.ts::*`
`validated-test:test/ralph-commands.test.ts::*` | + +### distributed-mesh + +**Distributed mesh, capability routing, rate limiting, KEDA autoscaling** + +Depends on: **a** (host-independent) Β· docs: [features/distributed-mesh](/squad/docs/features/distributed-mesh/) Β· [features/capability-routing](/squad/docs/features/capability-routing/) Β· [features/rate-limiting](/squad/docs/features/rate-limiting/) Β· [features/keda-scaling](/squad/docs/features/keda-scaling/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Fleet/watch-side features; the interactive host is not involved. | `validated-test:test/watch-fleet-dispatch.test.ts::*`
`validated-test:test/rate-limiting.test.ts::*`
`validated-test:test/watch-rate-limit.test.ts::*` | + +### aspire-dashboard + +**Aspire dashboard / OTel observability (`squad aspire`)** + +Depends on: **a** (host-independent) Β· docs: [scenarios/aspire-dashboard](/squad/docs/scenarios/aspire-dashboard/) Β· [scenarios/production-observability](/squad/docs/scenarios/production-observability/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | CLI launches the dashboard; OTel export from the SDK runtime. | `validated-test:test/aspire-command.test.ts::*`
`validated-test:test/otel-export.test.ts::*` | + +### gh-aw + +**GitHub Agentic Workflows (gh-aw) integration** + +Depends on: **e** Β· docs: [guide/gh-aw](/squad/docs/guide/gh-aw/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Workflows in `workflows/*.md`; verifier + e2e scripts. | `validated-test:test/gh-aw-enlistment-skill.test.ts::*`
`static-only` | +| `claude` | β€” n/a | πŸ“„ static-only | Runs in GitHub Actions with the Copilot engine; the local host is irrelevant. | `static-only` | +| `kiro` | β€” n/a | πŸ“„ static-only | Runs in GitHub Actions with the Copilot engine; the local host is irrelevant. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `static-only` | +| `opencode` | β€” n/a | πŸ“„ static-only | Runs in GitHub Actions with the Copilot engine; the local host is irrelevant. | `static-only` | +| `cursor` | β€” n/a | πŸ“„ static-only | Runs in GitHub Actions with the Copilot engine; the local host is irrelevant. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `static-only` | +| `codex` | β€” n/a | πŸ“„ static-only | Runs in GitHub Actions with the Copilot engine; the local host is irrelevant. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `static-only` | +| `antigravity` | β€” n/a | πŸ“„ static-only | Runs in GitHub Actions with the Copilot engine; the local host is irrelevant. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `static-only` | + +### sdk-first-mode + +**SDK-first mode (`squad.config.ts`, `squad build`, `squad migrate`)** + +Depends on: **a** (host-independent) Β· docs: [sdk-first-mode](/squad/docs/sdk-first-mode/) Β· [reference/sdk](/squad/docs/reference/sdk/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Compiles to the same `.squad/` markdown every host consumes. | `validated-test:test/migrate.test.ts::*` | + +### doctor-health-nap + +**Maintenance CLIs (`squad doctor`, `squad health`, `squad nap`, `squad upgrade`)** + +Depends on: **a** (host-independent) Β· docs: [reference/cli](/squad/docs/reference/cli/) Β· [scenarios/upgrading](/squad/docs/scenarios/upgrading/) Β· [scenarios/troubleshooting](/squad/docs/scenarios/troubleshooting/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Pure CLI; `upgrade --client` refreshes every configured host projection. | `validated-test:test/cli/doctor.test.ts::*`
`validated-test:test/cli/upgrade.test.ts::*`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace` | + +### client-projection + +**Squad 2.0 `--client` projection (coordinator file + MCP config per host, rollback)** + +Depends on: **a, d** Β· docs: [concepts/squad-2-0-architecture](/squad/docs/concepts/squad-2-0-architecture/) Β· [scenarios/using-squad-across-clients](/squad/docs/scenarios/using-squad-across-clients/) Β· [scenarios/client-compatibility](/squad/docs/scenarios/client-compatibility/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts`
`validated-test:test/clients-real-cli.test.ts::claude discovers the squad subagents and parses .mcp.json` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts`
`validated-test:test/clients-real-cli.test.ts::kiro validates and lists the squad agent` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts`
`validated-test:test/clients-real-cli.test.ts::opencode loads squad as a primary agent and connects the MCP server` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts`
`validated-test:test/clients-real-cli.test.ts::cursor-agent lists the squad_state server from .cursor/mcp.json (read-only)` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts`
`validated-test:test/clients-real-cli.test.ts::codex loads the project config (trusted), sees squad_state MCP, discovers the squad TOML role, and activates coordinator instructions on spawn` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | `installClients()` writes host-native files idempotently; real CLIs load them. | `validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts`
`validated-test:test/clients-real-cli.test.ts::antigravity discovers the squad agent` | + +### squad-state-mcp-bridge + +**`squad_state` MCP bridge reachable from the host (stdio, host-prefixed tool names)** + +Depends on: **c, d** Β· docs: [concepts/squad-2-0-architecture](/squad/docs/concepts/squad-2-0-architecture/) Β· [reference/tools-and-hooks](/squad/docs/reference/tools-and-hooks/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients-real-cli.test.ts::claude discovers the squad subagents and parses .mcp.json`
`validated-manual:lab:smoke-roster@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::claude --agent squad reads the roster through mcp__squad_state__squad_state_read` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients-real-cli.test.ts::kiro validates and lists the squad agent`
`static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients-real-cli.test.ts::opencode loads squad as a primary agent and connects the MCP server`
`validated-manual:lab:smoke-roster@2026-10-22`
`validated-test:test/squad-20-host-feature-matrix.test.ts::opencode --agent squad reads the roster through squad_state_squad_state_read` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients-real-cli.test.ts::cursor-agent lists the squad_state server from .cursor/mcp.json (read-only)`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients-real-cli.test.ts::codex loads the project config (trusted), sees squad_state MCP, discovers the squad TOML role, and activates coordinator instructions on spawn`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory`
`validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads`
`validated-test:test/clients-real-cli.test.ts::antigravity discovers the squad agent`
`static-only` | + +### capability-negotiation + +**Capability negotiation (client ∩ backend ∩ policy)** + +Depends on: **c** Β· docs: [concepts/squad-2-0-architecture](/squad/docs/concepts/squad-2-0-architecture/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | `CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection` | + +### experimental-backend + +**Experimental conversation backend (`squad_backend_*`, durable-http, approvals, resume)** + +Depends on: **c** Β· docs: [concepts/squad-2-0-architecture](/squad/docs/concepts/squad-2-0-architecture/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Opt-in tools over the same MCP server; backend semantics are host-independent. | `validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle`
`validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect` | + +### process-hygiene + +**Process hygiene (never kill by image name; PID-only)** + +Depends on: **b** Β· docs: [scenarios/troubleshooting](/squad/docs/scenarios/troubleshooting/) Β· canonical sections: `Constraints` + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `claude` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `kiro` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `opencode` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `cursor` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `codex` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | +| `antigravity` | βœ… supported | πŸ§ͺ validated-test | Digest Β§22–23. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `validated-test:test/clients.test.ts::coordinator behavioral-contract parity`
`static-only` | + +### subagent-mcp-inheritance + +**Specialists (subagents) can reach `squad_state` tools themselves** + +Depends on: **d** Β· docs: [concepts/squad-2-0-architecture](/squad/docs/concepts/squad-2-0-architecture/) + +| Host | Capability | Validation | Mechanism | Evidence | +|------|------------|------------|-----------|----------| +| `copilot` | βœ… supported | πŸ“„ static-only | `task` subagents inherit the session MCP servers. | `static-only` | +| `claude` | βœ… supported | πŸ–₯️ validated-live | Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents). _Live: Galois/Fermat/Scribe each called `squad_state_*` tools from inside their spawn (history appended, inbox drained)._ | `validated-manual:lab:parallel-fanout@2026-10-22` | +| `kiro` | βœ… supported | β›” blocked β€” live run blocked on the reference machine: kiro-cli chat failed: "The monthly usage limit has been reached". | Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents). _Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine._ | `static-only` | +| `opencode` | βœ… supported | πŸ–₯️ validated-live | Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents). _Live: Galois/Fermat/Scribe each called `squad_state_*` tools from inside their spawn (history appended, inbox drained)._ | `validated-manual:lab:parallel-fanout@2026-10-22` | +| `cursor` | βœ… supported | β›” blocked β€” live run blocked on the reference machine: cursor-agent -p failed: "You've hit your usage limit". | Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents). _Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine._ | `static-only` | +| `codex` | βœ… supported | ❔ untested | Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents). _No Codex binary or ChatGPT/API auth on the reference machine; static-only._ | `static-only` | +| `antigravity` | ⚠️ degraded | β›” blocked β€” live run blocked on the reference machine: agy -p failed: RESOURCE_EXHAUSTED 429 "Individual quota reached" (resets in ~75h). | `invoke_subagent` starts with a clean context; MCP attached via agent frontmatter may not propagate β€” specialists return results for the coordinator to persist. _Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine._ | `static-only` | + +## Live run log + +Headless real-CLI runs behind the `validated-manual:lab:` evidence entries above (only `pass`/`partial` runs raise a cell to `validated-live`). Each run drove the host's projected Squad coordinator against a real model in a throwaway repository; transcripts are kept outside the repository. + +| Date | Host | Scenario | Outcome | Observed tools | Notes | +|------|------|----------|---------|----------------|-------| +| 2026-10-22 | `claude` | smoke-roster | βœ… pass | `mcp__squad_state__squad_state_read` | Roster + testing owner from team.md/routing.md via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion). | +| 2026-10-22 | `claude` | init-mode | βœ… pass | `mcp__squad_state__squad_state_read`, `Bash` | Empty roster β†’ proposed 4 specialists, cast each with `squad cast --name`, stopped after reporting the roster. | +| 2026-10-22 | `claude` | upstream | βœ… pass | `mcp__squad_state__squad_state_read`, `Bash` | Found SEVEN-SECOND-TIMEOUT decision and ORG-LOG-PREFIX skill by reading the upstream path from upstream.json. | +| 2026-10-22 | `claude` | cross-squad | βœ… pass | `Read`, `Bash` | Loaded cross-squad + cross-squad-communication skills, read squad-registry.json and peer manifest, prepared `squad delegate peer-b …`, no issue created, no ad-hoc subagents. | +| 2026-10-22 | `claude` | mono-subfolder | βœ… pass | `mcp__squad_state__squad_state_read` | From packages/api with --mcp-config /.mcp.json; natively the server is "Pending approval" (F5). | +| 2026-10-22 | `claude` | satellite-remote | βœ… pass | `mcp__squad_state__squad_state_read`, `Read` | Roster served from teamRoot ..\base; no Init Mode. | +| 2026-10-22 | `claude` | ado-platform | βœ… pass | `Bash`, `Read` | Detected Azure DevOps from the remote; consulted issue-lifecycle.md; proposed az boards/az repos commands; ran only read-only checks. | +| 2026-10-22 | `claude` | github-issues-readonly | βœ… pass | `Bash`, `mcp__squad_state__squad_state_read` | gh prerequisites checked; 5 squad-labelled issues listed read-only and routed via routing.md (Lead triages unknown squad:* labels). | +| 2026-10-22 | `claude` | state-orphan | βœ… pass | `mcp__squad_state__squad_state_health`, `mcp__squad_state__squad_decide`, `mcp__squad_state__squad_state_list` | Decision committed to the squad-state orphan branch; working tree untouched; health reported the storage class, not "orphan" (F6). | +| 2026-10-22 | `claude` | state-twolayer | βœ… pass | `mcp__squad_state__squad_state_health`, `mcp__squad_state__squad_decide`, `mcp__squad_state__squad_state_list` | Decision committed to the squad-state branch (two-layer); health reported the storage class, not "two-layer" (F6). | +| 2026-10-22 | `claude` | skills-precedence | βœ… pass | `Bash` | .squad/skills/deploy-rules (DEPLOY-ALPHA) won over .github and .claude copies; no spawn in the dry run. | +| 2026-10-22 | `claude` | directive-capture | βœ… pass | `mcp__squad_state__squad_decide` | Persistent "always use tabs" directive recorded via squad_decide and acknowledged. | +| 2026-10-22 | `claude` | reviewer-lockout | βœ… pass | `Agent`, `mcp__squad_state__squad_decide` | Galois authored, Fermat REJECTed ("missing tests"), Galois locked out, revision assigned to Noether, verdict recorded via squad_decide. | +| 2026-10-22 | `claude` | ralph-no-repo | βœ… pass | `Bash` | No git remote β†’ Ralph reported it and stopped without routing work. | +| 2026-10-22 | `claude` | worktree-spawn | βœ… pass | `Bash`, `Read` | Created sibling worktree base-12 on squad/12-add-health per worktree-reference.md. | +| 2026-10-22 | `claude` | parallel-fanout | βœ… pass | `Agent`, `mcp__squad_state__squad_state_append`, `mcp__squad_state__squad_state_health` | Two specialists spawned in one turn (Claude: background subagents), each appended its own history via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion); Scribe drained the inbox. | +| 2026-10-22 | `opencode` | smoke-roster | βœ… pass | `squad_state_squad_state_read` | Roster + testing owner from team.md/routing.md via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion). | +| 2026-10-22 | `opencode` | init-mode | βœ… pass | `squad_state_squad_state_read`, `Bash` | Empty roster β†’ proposed 4 specialists, cast each with `squad cast --name`, stopped after reporting the roster. | +| 2026-10-22 | `opencode` | upstream | ⚠️ partial | `squad_state_squad_state_read`, `Bash` | Found the upstream decision; missed the `.copilot/skills` skill living beside the upstream `.squad/`. | +| 2026-10-22 | `opencode` | cross-squad | βœ… pass | `Read`, `Bash` | Loaded cross-squad + cross-squad-communication skills, read squad-registry.json and peer manifest, prepared `squad delegate peer-b …`, no issue created, no ad-hoc subagents. | +| 2026-10-22 | `opencode` | mono-subfolder | βœ… pass | `squad_state_squad_state_read` | From packages/api; opencode.json and agent resolved from the repo root. | +| 2026-10-22 | `opencode` | satellite-remote | βœ… pass | `squad_state_squad_state_read`, `Read` | Roster served from teamRoot ..\base; no Init Mode. | +| 2026-10-22 | `opencode` | ado-platform | βœ… pass | `Bash`, `Read` | Detected Azure DevOps from the remote; consulted issue-lifecycle.md; proposed az boards/az repos commands; ran only read-only checks. | +| 2026-10-22 | `opencode` | github-issues-readonly | βœ… pass | `Bash`, `squad_state_squad_state_read` | gh prerequisites checked; 5 squad-labelled issues listed read-only and routed via routing.md (Lead triages unknown squad:* labels). | +| 2026-10-22 | `opencode` | state-orphan | βœ… pass | `squad_state_squad_state_health`, `squad_state_squad_decide`, `squad_state_squad_state_list` | Decision committed to the squad-state orphan branch; working tree untouched; health reported the storage class, not "orphan" (F6). | +| 2026-10-22 | `opencode` | state-twolayer | βœ… pass | `squad_state_squad_state_health`, `squad_state_squad_decide`, `squad_state_squad_state_list` | Decision committed to the squad-state branch (two-layer); health reported the storage class, not "two-layer" (F6). | +| 2026-10-22 | `opencode` | skills-precedence | βœ… pass | `Bash` | .squad/skills/deploy-rules (DEPLOY-ALPHA) won over .github and .claude copies; no spawn in the dry run. | +| 2026-10-22 | `opencode` | directive-capture | βœ… pass | `squad_state_squad_decide` | Persistent "always use tabs" directive recorded via squad_decide and acknowledged. | +| 2026-10-22 | `opencode` | reviewer-lockout | βœ… pass | `task`, `squad_state_squad_decide` | Galois authored, Fermat REJECTed ("missing tests"), Galois locked out, revision assigned to Noether, verdict recorded via squad_decide. | +| 2026-10-22 | `opencode` | ralph-no-repo | βœ… pass | `Bash` | No git remote β†’ Ralph reported it and stopped without routing work. | +| 2026-10-22 | `opencode` | worktree-spawn | βœ… pass | `Bash`, `Read` | Created sibling worktree base-12 on squad/12-add-health per worktree-reference.md. | +| 2026-10-22 | `opencode` | parallel-fanout | βœ… pass | `task`, `squad_state_squad_state_append`, `squad_state_squad_state_health` | Two specialists spawned in one turn (Claude: background subagents), each appended its own history via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion); Scribe drained the inbox. | +| 2026-10-22 | `kiro` | smoke-roster | β›” blocked | β€” | kiro-cli chat failed: "The monthly usage limit has been reached". | +| 2026-10-22 | `antigravity` | smoke-roster | β›” blocked | β€” | agy -p failed: RESOURCE_EXHAUSTED 429 "Individual quota reached" (resets in ~75h). | +| 2026-10-22 | `cursor` | smoke-roster | β›” blocked | β€” | cursor-agent -p failed: "You've hit your usage limit". | + diff --git a/docs/src/content/docs/scenarios/using-squad-across-clients.md b/docs/src/content/docs/scenarios/using-squad-across-clients.md index 4fc46a6e8..fd420faf7 100644 --- a/docs/src/content/docs/scenarios/using-squad-across-clients.md +++ b/docs/src/content/docs/scenarios/using-squad-across-clients.md @@ -48,7 +48,7 @@ Every host gets one coordinator file. Team members are not projected as separate 2. Open `.claude/agents/squad.md` to inspect the coordinator prompt. 3. Confirm `.mcp.json` contains `squad_state` and `.gitignore` contains the managed `.claude/worktrees/` block. 4. Check `CLAUDE.md` for the managed Squad marker block (`` / ``); your notes outside the block are preserved. -5. Run `claude --agent squad --mcp-config .mcp.json` or delegate to the `squad` subagent. Interactive Claude Code does not load project-scoped `.mcp.json` servers until they are approved, so pass the config explicitly. +5. Run `claude --agent squad --mcp-config .mcp.json` or delegate to the `squad` subagent. Claude Code does not load project-scoped `.mcp.json` servers until they are approved (`claude mcp list` shows `squad_state … Pending approval`); approve them once interactively, or always pass the config explicitly. **Headless runs (`claude -p …`, CI, scripts) must pass `--mcp-config .mcp.json`:** without it the coordinator has no `squad_state_*` tools, falls back to reading `.squad/team.md` directly, and halts on the state-backend handshake for `orphan` / `two-layer` backends. Squad deliberately does not write `enableAllProjectMcpServers: true` into `.claude/settings.json` for you. ## Kiro walkthrough diff --git a/docs/src/content/docs/tour-gitlab-issues.md b/docs/src/content/docs/tour-gitlab-issues.md index 4d955b89d..2478f60a2 100644 --- a/docs/src/content/docs/tour-gitlab-issues.md +++ b/docs/src/content/docs/tour-gitlab-issues.md @@ -1,6 +1,6 @@ # GitLab Issues Walkthrough -> **πŸ§ͺ Experimental.** GitLab Issues Mode is new. Commands, behavior, and integration details may change. [Feedback welcome.](https://github.com/bradygaster/squad/issues) +> **πŸ—ΊοΈ Planned, not shipped.** Squad 2.0 has no GitLab platform adapter (see [GitLab Issues Mode](features/gitlab-issues.md)). This walkthrough describes the intended experience; today it only works if you ask the coordinator to use `glab` ad hoc. A step-by-step tour of Squad's GitLab Issues workflow. This connects your team to a GitLab repository's issue tracker so agents can pick up issues, create branches, open Merge Requests, and handle review feedback. diff --git a/docs/src/navigation.ts b/docs/src/navigation.ts index d7df86d37..f473e91d0 100644 --- a/docs/src/navigation.ts +++ b/docs/src/navigation.ts @@ -164,6 +164,7 @@ export const NAV_SECTIONS: NavSection[] = [ { title: 'Config', slug: 'reference/config' }, { title: 'Container Image', slug: 'reference/container-image' }, { title: 'State Backend Selection', slug: 'reference/state-backend-selection' }, + { title: 'Host Feature Matrix', slug: 'reference/host-feature-matrix' }, { title: 'Glossary', slug: 'reference/glossary' }, ], }, diff --git a/scripts/render-host-feature-matrix.mjs b/scripts/render-host-feature-matrix.mjs new file mode 100644 index 000000000..bdeba830e --- /dev/null +++ b/scripts/render-host-feature-matrix.mjs @@ -0,0 +1,206 @@ +#!/usr/bin/env node +/** + * Render docs/src/content/docs/reference/host-feature-matrix.md from + * test-fixtures/spec/suite-v0.2/host-feature-matrix.json. + * + * The JSON is the source of truth (hand-maintained, asserted by + * test/squad-20-host-feature-matrix.test.ts). Re-run after editing it: + * + * node scripts/render-host-feature-matrix.mjs # write the page + * node scripts/render-host-feature-matrix.mjs --check # exit 1 if the page is stale + * node scripts/render-host-feature-matrix.mjs --summary # print per-host counts (for reports) + */ +import fs from 'node:fs'; +import path from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); +export const MATRIX_PATH = path.join(ROOT, 'test-fixtures', 'spec', 'suite-v0.2', 'host-feature-matrix.json'); +export const PAGE_PATH = path.join(ROOT, 'docs', 'src', 'content', 'docs', 'reference', 'host-feature-matrix.md'); + +/** Capability axis: what the host can do. */ +export const CAPABILITIES = ['supported', 'degraded', 'unsupported', 'n/a']; +/** Validation axis: how confident the capability claim is. */ +export const VALIDATION_LEVELS = ['validated-live', 'validated-test', 'static-only', 'untested', 'blocked']; +const CAPABILITY_ICON = { supported: 'βœ…', degraded: '⚠️', unsupported: '❌', 'n/a': 'β€”' }; +const VALIDATION_ICON = { 'validated-live': 'πŸ–₯️', 'validated-test': 'πŸ§ͺ', 'static-only': 'πŸ“„', untested: '❔', blocked: 'β›”' }; + +export function evidenceKind(entry) { + return entry.split(':')[0]; +} + +/** True when the cell lists a recorded live run (`validated-manual:lab:…`) in its evidence. */ +export function hasLiveRun(cell) { + return cell.evidence.some((v) => evidenceKind(v) === 'validated-manual'); +} + +export function summarize(matrix) { + const hosts = Object.keys(matrix.hosts); + const out = {}; + for (const h of hosts) { + const s = { supported: 0, degraded: 0, unsupported: 0, 'n/a': 0, 'validated-live': 0, 'validated-test': 0, 'static-only': 0, untested: 0, blocked: 0, expectedFailures: 0 }; + for (const f of matrix.features) { + const c = f.cells[h]; + s[c.capability]++; + s[c.validation]++; + if (c.expectedFailure) s.expectedFailures++; + } + out[h] = s; + } + return out; +} + +export function render(matrix) { + const hosts = Object.keys(matrix.hosts); + const lines = []; + lines.push('---'); + lines.push('title: Host Feature Matrix'); + lines.push('description: Which Squad features work on which host (Copilot, Claude Code, Kiro, OpenCode, Cursor, Codex, Antigravity), what each depends on, and how each cell has been validated.'); + lines.push('order: 16'); + lines.push('---'); + lines.push(''); + lines.push('# Host Feature Matrix'); + lines.push(''); + lines.push(''); + lines.push(''); + lines.push('> πŸ”— Related: [Squad 2.0 Architecture](/squad/docs/concepts/squad-2-0-architecture/) Β· [Using Squad Across Clients](/squad/docs/scenarios/using-squad-across-clients/) Β· [Client Compatibility](/squad/docs/scenarios/client-compatibility/)'); + lines.push(''); + lines.push(`Squad features fall into five dependency classes. Features that depend only on the \`squad\` CLI (class **a**) behave identically everywhere because the host is not involved. Everything else depends on what the host's coordinator file contains, whether the \`squad_state\` MCP bridge is reachable, and what the host runtime can do. The machine-readable source is \`${path.relative(ROOT, MATRIX_PATH).replace(/\\/g, '/')}\` (protocol \`${matrix.protocol}\`).`); + lines.push(''); + lines.push('## Dependency classes'); + lines.push(''); + lines.push('| Class | Depends on |'); + lines.push('|-------|------------|'); + for (const [k, v] of Object.entries(matrix.dependencyClasses)) lines.push(`| **${k}** | ${v} |`); + lines.push(''); + lines.push('## Legend'); + lines.push(''); + lines.push('Every cell has two independent values. **Capability** says what the host can do; **validation** says how that claim was established. Neither implies the other: a `supported` cell may be only `static-only`, and an `unsupported` cell can be `validated-test` (a test proves the gap).'); + lines.push(''); + lines.push('| Capability | Meaning |'); + lines.push('|------------|---------|'); + for (const [k, v] of Object.entries(matrix.capabilities)) lines.push(`| ${CAPABILITY_ICON[k]} \`${k}\` | ${v} |`); + lines.push(''); + lines.push('| Validation | Meaning |'); + lines.push('|------------|---------|'); + for (const [k, v] of Object.entries(matrix.validationLevels)) lines.push(`| ${VALIDATION_ICON[k]} \`${k}\` | ${v} |`); + lines.push(''); + lines.push('| Evidence entry | Meaning |'); + lines.push('|----------------|---------|'); + for (const [k, v] of Object.entries(matrix.evidenceKinds)) lines.push(`| \`${k}\` | ${v} |`); + lines.push(''); + lines.push('Each matrix cell shows **capability validation** (for example `βœ… πŸ§ͺ` = supported, covered by an automated test; `❌ πŸ§ͺ` = unsupported, proven by an expected-failure test; `βœ… πŸ“„` = supported, statically inspected only; `βœ… β›”` = supported on paper, the live attempt for this host was blocked).'); + lines.push(''); + lines.push('## Hosts'); + lines.push(''); + lines.push('| Host | CLI | Coordinator file | MCP config | Subagents | Background | Per-spawn model | Subagents inherit MCP |'); + lines.push('|------|-----|------------------|------------|-----------|------------|-----------------|-----------------------|'); + for (const h of hosts) { + const m = matrix.hosts[h]; + const yn = (b) => (b ? 'yes' : 'no'); + const cliNote = m.installedOnReferenceMachine ? (m.referenceMachineNote ? ` (${m.referenceMachineNote})` : '') : ' (not on the reference machine β†’ static-only)'; + lines.push(`| **${m.name}** (\`${h}\`) | \`${m.cli}\`${cliNote} | ${m.coordinatorFile} | ${m.mcpConfig} | ${yn(m.runtime.subagents)} | ${yn(m.runtime.backgroundRuns)} | ${yn(m.runtime.perSpawnModel)} | ${yn(m.runtime.mcpInheritedBySubagents)} |`); + } + lines.push(''); + lines.push('## Summary'); + lines.push(''); + const sum = summarize(matrix); + lines.push('Capability counts and validation counts are independent breakdowns of the same cells (each row sums to the feature count twice).'); + lines.push(''); + lines.push('| Host | βœ… supported | ⚠️ degraded | ❌ unsupported | β€” n/a | πŸ–₯️ validated-live | πŸ§ͺ validated-test | πŸ“„ static-only | ❔ untested | β›” blocked | of which expected-failure gaps |'); + lines.push('|------|-------------|-------------|----------------|-------|-------------------|-------------------|----------------|------------|------------|--------------------------------|'); + for (const h of hosts) { + const s = sum[h]; + lines.push(`| \`${h}\` | ${s.supported} | ${s.degraded} | ${s.unsupported} | ${s['n/a']} | ${s['validated-live']} | ${s['validated-test']} | ${s['static-only']} | ${s.untested} | ${s.blocked} | ${s.expectedFailures} |`); + } + lines.push(''); + if (Array.isArray(matrix.expectedFailures) && matrix.expectedFailures.length > 0) { + lines.push('## Expected failures (`it.fails`)'); + lines.push(''); + lines.push('These digest gaps are pinned as expected failures, one test per host and gap: the `[]` test turns red the moment a stack adds the section for that host. Until then the cell is **unsupported** for that host (validated by the failing test), never degraded or supported.'); + lines.push(''); + lines.push('| Feature | Test (title; each generated test appends the host as `[]`) | Hosts | Meaning |'); + lines.push('|---------|-----------------------------|-------|---------|'); + for (const e of matrix.expectedFailures) { + lines.push(`| [${e.featureId}](#${e.featureId}) | \`${e.test.replace(/\|/g, '\\|')}\` (${e.kind}${e.perHost ? ', per host' : ''}) | ${(e.hosts ?? []).map((h) => `\`${h}\``).join(' ')} | ${e.meaning} |`); + } + lines.push(''); + } + if (Array.isArray(matrix.limitations) && matrix.limitations.length > 0) { + lines.push('## Known limitations of this evidence'); + lines.push(''); + for (const l of matrix.limitations) lines.push(`- ${l}`); + lines.push(''); + } + lines.push('## Matrix'); + lines.push(''); + const areas = [...new Set(matrix.features.map((f) => f.area))]; + for (const area of areas) { + lines.push(`### ${area}`); + lines.push(''); + lines.push(`| Feature | Deps | ${hosts.map((h) => `\`${h}\``).join(' | ')} |`); + lines.push(`|---------|------|${hosts.map(() => '---').join('|')}|`); + for (const f of matrix.features.filter((x) => x.area === area)) { + const cells = hosts.map((h) => { + const c = f.cells[h]; + return `${CAPABILITY_ICON[c.capability]} ${VALIDATION_ICON[c.validation]}`; + }); + lines.push(`| [${f.name.replace(/\|/g, '\\|')}](#${f.id}) | ${f.dependsOn.join(', ')}${f.hostIndependent ? ' (host-independent)' : ''} | ${cells.join(' | ')} |`); + } + lines.push(''); + } + lines.push('## Per-feature detail'); + lines.push(''); + for (const f of matrix.features) { + lines.push(`### ${f.id}`); + lines.push(''); + lines.push(`**${f.name}**`); + lines.push(''); + const docs = (f.docs ?? []).map((d) => `[${d}](/squad/docs/${d}/)`).join(' Β· '); + const sections = f.canonicalSections?.length ? ` Β· canonical sections: ${f.canonicalSections.map((s) => `\`${s}\``).join(', ')}` : ''; + lines.push(`Depends on: **${f.dependsOn.join(', ')}**${f.hostIndependent ? ' (host-independent)' : ''}${docs ? ` Β· docs: ${docs}` : ''}${sections}`); + lines.push(''); + lines.push('| Host | Capability | Validation | Mechanism | Evidence |'); + lines.push('|------|------------|------------|-----------|----------|'); + for (const h of hosts) { + const c = f.cells[h]; + const notes = c.notes ? ` _${c.notes}_` : ''; + const flags = [c.expectedFailure ? ' (expected failure)' : '', c.blockedReason ? ` β€” ${c.blockedReason}` : ''].join(''); + const evidence = c.evidence.map((v) => `\`${v}\``).join('
') || 'β€”'; + lines.push(`| \`${h}\` | ${CAPABILITY_ICON[c.capability]} ${c.capability} | ${VALIDATION_ICON[c.validation]} ${c.validation}${flags.replace(/\|/g, '\\|')} | ${c.mechanism.replace(/\|/g, '\\|')}${notes.replace(/\|/g, '\\|')} | ${evidence.replace(/\|/g, '\\|')} |`); + } + lines.push(''); + } + if (matrix.liveRuns?.length) { + lines.push('## Live run log'); + lines.push(''); + lines.push('Headless real-CLI runs behind the `validated-manual:lab:` evidence entries above (only `pass`/`partial` runs raise a cell to `validated-live`). Each run drove the host\'s projected Squad coordinator against a real model in a throwaway repository; transcripts are kept outside the repository.'); + lines.push(''); + lines.push('| Date | Host | Scenario | Outcome | Observed tools | Notes |'); + lines.push('|------|------|----------|---------|----------------|-------|'); + const OUTCOME = { pass: 'βœ… pass', partial: '⚠️ partial', fail: 'πŸ”΄ fail', blocked: 'β›” blocked' }; + for (const r of matrix.liveRuns) lines.push(`| ${r.date} | \`${r.host}\` | ${r.scenario} | ${OUTCOME[r.outcome] ?? r.outcome} | ${(r.observedTools ?? []).map((t) => `\`${t}\``).join(', ') || 'β€”'} | ${(r.notes ?? '').replace(/\|/g, '\\|')} |`); + lines.push(''); + } + return lines.join('\n') + '\n'; +} + +const isMain = process.argv[1] && path.resolve(process.argv[1]) === fileURLToPath(import.meta.url); +if (isMain) { + const matrix = JSON.parse(fs.readFileSync(MATRIX_PATH, 'utf8')); + if (process.argv.includes('--summary')) { + console.log(JSON.stringify(summarize(matrix), null, 2)); + } else if (process.argv.includes('--check')) { + // Compare line-ending-insensitively (LF and CRLF checkouts both pass): autocrlf stores the page with CRLF. + const expected = render(matrix).replace(/\r\n/g, '\n'); + const actual = (fs.existsSync(PAGE_PATH) ? fs.readFileSync(PAGE_PATH, 'utf8') : '').replace(/\r\n/g, '\n'); + if (expected !== actual) { + console.error(`${path.relative(ROOT, PAGE_PATH)} is stale; run: node scripts/render-host-feature-matrix.mjs`); + process.exit(1); + } + console.log('host-feature-matrix.md is up to date'); + } else { + fs.writeFileSync(PAGE_PATH, render(matrix)); + console.log(`wrote ${path.relative(ROOT, PAGE_PATH)}`); + } +} diff --git a/test-fixtures/spec/suite-v0.2/host-feature-matrix.json b/test-fixtures/spec/suite-v0.2/host-feature-matrix.json new file mode 100644 index 000000000..9299c7c3c --- /dev/null +++ b/test-fixtures/spec/suite-v0.2/host-feature-matrix.json @@ -0,0 +1,5082 @@ +{ + "protocol": "squad-protocol-v2.0-rc1", + "description": "Feature Γ— host matrix for Squad: what each Squad capability depends on, how it is realised per host, and how (if at all) it has been validated.", + "dependencyClasses": { + "a": "squad CLI only (host-agnostic; the host is not involved)", + "b": "coordinator-prompt behavior (the section must be present in the host's coordinator file or reachable on demand)", + "c": "squad_state / memory.* MCP tools (state-mcp bridge reachable from the host)", + "d": "host runtime capability (subagent spawn, background tasks, shell, file ops, sql, per-spawn model, MCP inheritance by subagents)", + "e": "platform CLI or MCP availability in the host (gh / glab / az / ADO MCP / GitHub MCP)" + }, + "capabilities": { + "supported": "The host can do this through the stated mechanism, with no known limitation.", + "degraded": "The host does this partially: it works, but with the stated limitation (for example a synchronous fallback, an on-demand path, or a host runtime gap).", + "unsupported": "The host cannot do this today β€” including every case where the coordinator section the feature relies on is absent from the host's projected digest. Stays unsupported until the section ships.", + "n/a": "Not applicable to this host (a Copilot-only surface or something that runs outside the host)." + }, + "validationLevels": { + "validated-test": "An automated test in this repository asserts the cell (see `evidence`; CLI/SDK tests are host-independent). For `unsupported` digest-gap cells this is the per-host `it.fails` that proves the section is absent.", + "validated-live": "A recorded headless run of the real host CLI against a real model passed on the reference machine (Claude Code and OpenCode only, 2026-10-22); the test-level evidence also applies.", + "static-only": "Only the projected/canonical text or the source was inspected; no automated or live evidence for this cell.", + "untested": "Nothing beyond static reading, and no live attempt was made for this host.", + "blocked": "A live run was attempted for this host and could not complete for an external reason (`blockedReason`); confidence is the same as `untested`." + }, + "evidenceKinds": { + "validated-test:::": "Automated test (name `*` = the whole file). The title must appear literally in the file.", + "validated-manual:lab:@": "A recorded live run (see the live run log) for this host and scenario.", + "static-only": "Marker: the cell was (also) read statically." + }, + "hosts": { + "copilot": { + "name": "GitHub Copilot (CLI / app / VS Code)", + "cli": "copilot", + "installedOnReferenceMachine": true, + "coordinatorFile": ".github/agents/squad.agent.md (canonical)", + "mcpConfig": ".mcp.json", + "runtime": { + "subagents": true, + "backgroundRuns": true, + "perSpawnModel": true, + "sqlTool": true, + "shell": true, + "mcpInheritedBySubagents": true + } + }, + "claude": { + "name": "Claude Code", + "cli": "claude", + "installedOnReferenceMachine": true, + "coordinatorFile": ".claude/agents/squad.md (digest) + CLAUDE.md block", + "mcpConfig": ".mcp.json", + "runtime": { + "subagents": true, + "backgroundRuns": false, + "perSpawnModel": false, + "sqlTool": false, + "shell": true, + "mcpInheritedBySubagents": true + } + }, + "kiro": { + "name": "Kiro CLI", + "cli": "kiro-cli", + "installedOnReferenceMachine": true, + "coordinatorFile": ".kiro/agents/squad.json + .kiro/steering/squad.md (manual)", + "mcpConfig": ".kiro/settings/mcp.json", + "runtime": { + "subagents": true, + "backgroundRuns": false, + "perSpawnModel": false, + "sqlTool": false, + "shell": true, + "mcpInheritedBySubagents": true + } + }, + "opencode": { + "name": "OpenCode", + "cli": "opencode", + "installedOnReferenceMachine": true, + "coordinatorFile": ".opencode/agents/squad.md (primary)", + "mcpConfig": "opencode.json (mcp.squad_state)", + "runtime": { + "subagents": true, + "backgroundRuns": true, + "perSpawnModel": false, + "sqlTool": false, + "shell": true, + "mcpInheritedBySubagents": true + } + }, + "cursor": { + "name": "Cursor", + "cli": "cursor-agent", + "installedOnReferenceMachine": true, + "coordinatorFile": ".cursor/rules/squad.mdc (alwaysApply: false) + .cursor/agents/squad.md", + "mcpConfig": ".cursor/mcp.json", + "runtime": { + "subagents": true, + "backgroundRuns": false, + "perSpawnModel": false, + "sqlTool": false, + "shell": true, + "mcpInheritedBySubagents": true + }, + "referenceMachineNote": "installed; the live smoke run was blocked by a usage limit (see live run log), so cells without a dedicated test are untested" + }, + "codex": { + "name": "OpenAI Codex", + "cli": "codex", + "installedOnReferenceMachine": false, + "coordinatorFile": ".codex/agents/squad.toml (developer_instructions) + AGENTS.md pointer", + "mcpConfig": ".codex/config.toml (mcp_servers.squad_state)", + "runtime": { + "subagents": true, + "backgroundRuns": false, + "perSpawnModel": false, + "sqlTool": false, + "shell": true, + "mcpInheritedBySubagents": true + } + }, + "antigravity": { + "name": "Google Antigravity", + "cli": "agy", + "installedOnReferenceMachine": true, + "coordinatorFile": ".agents/agents/squad.md + GEMINI.md block", + "mcpConfig": "agent frontmatter mcpServers (or `agy mcp add`)", + "runtime": { + "subagents": true, + "backgroundRuns": false, + "perSpawnModel": false, + "sqlTool": false, + "shell": true, + "mcpInheritedBySubagents": false + } + } + }, + "features": [ + { + "id": "init-mode-casting", + "name": "Init Mode & casting (`squad init`, `squad cast --name`, casting registry)", + "area": "Core", + "docs": [ + "features/team-setup", + "concepts/your-team" + ], + "canonicalSections": [ + "Init Mode", + "Casting & Persistent Naming" + ], + "dependsOn": [ + "a", + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "validated-manual:lab:init-mode@2026-10-22" + ], + "notes": "Live: cast 4 members via `squad cast --name` (registry pair valid); ignored the requested descriptive universe and used Apollo 13 names." + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "validated-manual:lab:init-mode@2026-10-22" + ], + "notes": "Live: cast 4 members via `squad cast --name` with descriptive names; registry pair valid." + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI scaffolds `.squad/`; coordinator Init Mode (digest Β§0) uses `squad_state_read team.md`, auto-confirms headless, casts via `squad cast --name`, never hand-edits `.squad/casting/`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::field findings from the live demo: Init Mode, scratch files, casting registry", + "validated-test:test/cli/init.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "routing-ownership", + "name": "Work routing by ownership (`routing.md`, one accountable owner, named requests)", + "area": "Core", + "docs": [ + "features/routing" + ], + "canonicalSections": [ + "Routing", + "Scope Control" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:smoke-roster@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:smoke-roster@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§2–3: route by `routing.md`, exactly one owner, explicit deliverables/exclusions.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "response-modes", + "name": "Response modes (Direct / Lightweight / Standard / Full) + \"feels heard\" acknowledgement", + "area": "Core", + "docs": [ + "features/response-modes" + ], + "canonicalSections": [ + "Response Mode Selection", + "Acknowledge Immediately β€” \"Feels Heard\"" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:smoke-roster@2026-10-22", + "validated-manual:lab:ralph-no-repo@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:smoke-roster@2026-10-22", + "validated-manual:lab:ralph-no-repo@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§10 carries all four modes and the acknowledge-then-spawn rule.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "model-selection", + "name": "Model / reasoning-effort / context-tier selection per spawn", + "area": "Core", + "docs": [ + "features/model-selection", + "scenarios/switching-models" + ], + "canonicalSections": [ + "Per-Agent Model Selection", + "Per-Agent Reasoning Effort", + "Per-Agent Context Tier" + ], + "dependsOn": [ + "b", + "d" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Canonical Β§Model Selection + `task` tool `model`/`reasoning_effort`/`context_tier` params; `.squad/config.json` overrides.", + "evidence": [ + "validated-test:test/model-selector-policy.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The CLI/SDK side works, but the projected digest carries no section for it, so the coordinator is not told about it on this host. Unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "`Task` has no per-call model; only subagent-definition `model:` frontmatter. Digest lacks the model-selection section.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Model is set per agent in `opencode.json` (`agent.squad.model`), not per `task` call; reasoning/context tiers unsupported.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Digest has no model-selection section (only `model-selection-reference.md` on demand); host dispatch primitive has no per-spawn model parameter, so the session model is inherited.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Record as a host limitation, not a bug: `squad.agent.md` already says not to rely on per-spawn model control cross-platform. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "parallel-fanout", + "name": "Parallel fan-out of independent specialists", + "area": "Core", + "docs": [ + "features/parallel-execution", + "concepts/parallel-work" + ], + "canonicalSections": [ + "Team Mode" + ], + "dependsOn": [ + "b", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-manual:lab:parallel-fanout@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-manual:lab:parallel-fanout@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§6 + every dispatch adapter says to issue independent spawns in one turn; all hosts declare the `subagents` token.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "background-agents", + "name": "Background agents (Scribe/Rai run non-blocking)", + "area": "Core", + "docs": [ + "features/parallel-execution" + ], + "canonicalSections": [ + "Shared Decision Architecture β€” Drop-Box Pattern" + ], + "dependsOn": [ + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`background-runs` token; `task` mode=background / `read_agent`.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts" + ] + }, + "claude": { + "capability": "degraded", + "validation": "validated-live", + "mechanism": "No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-manual:lab:parallel-fanout@2026-10-22" + ], + "notes": "F7: Claude Code 2.1.296 actually ran the two specialist `Agent` spawns in the background (`subagent_stats.started_in_background`); the `background-runs` token is absent from the matrix, so Squad under-declares Claude here." + }, + "kiro": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "`background-runs` token declared; `task` subagents run as child sessions.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-manual:lab:parallel-fanout@2026-10-22" + ] + }, + "cursor": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts" + ] + }, + "antigravity": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "No `background-runs` token: Scribe/Rai run synchronously as the last spawn of the turn instead of in the background.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts" + ] + } + } + }, + { + "id": "scribe-decisions-history", + "name": "Scribe, decisions drop-box, agent history, orchestration log", + "area": "Memory", + "docs": [ + "features/memory", + "concepts/memory-and-knowledge" + ], + "canonicalSections": [ + "Shared Decision Architecture β€” Drop-Box Pattern", + "Built-in Support Agents" + ], + "dependsOn": [ + "b", + "c" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-manual:lab:parallel-fanout@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-manual:lab:parallel-fanout@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§5/Β§11; writes go through `squad_decide` / `squad_state_append`; Scribe merges inbox β†’ `decisions.md`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "directive-capture", + "name": "Directive capture (\"always…/never…\" β†’ `squad_decide`)", + "area": "Memory", + "docs": [ + "features/directives" + ], + "canonicalSections": [ + "Directive Capture" + ], + "dependsOn": [ + "b", + "c" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:directive-capture@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:directive-capture@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§16 captures persistent directives via `squad_decide` and dispatches implementation separately.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "memory-governance", + "name": "Memory governance (`memory.*` tools, classes, promote/audit)", + "area": "Memory", + "docs": [ + "features/memory" + ], + "canonicalSections": [ + "Memory Governance Tools" + ], + "dependsOn": [ + "c" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "validated-manual:lab:state-orphan@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "validated-manual:lab:state-orphan@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`memory.*` aliases live in the same `squad_state` MCP server; digest Β§16 prefers them when exposed.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/memory-governance.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "state-backends", + "name": "State backends (`local` / `orphan` / `two-layer`) + handshake", + "area": "Memory", + "docs": [ + "features/state-backends", + "reference/state-backend-selection" + ], + "canonicalSections": [ + "State & Team Root Resolution (before mode check)", + "Memory Governance Tools" + ], + "dependsOn": [ + "a", + "c", + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-manual:lab:state-orphan@2026-10-22", + "validated-manual:lab:state-twolayer@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ], + "notes": "F6: `squad_state_health` answered \"State backend storage: StateBackendStorageAdapter\" instead of the backend name the digest promises." + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-manual:lab:state-orphan@2026-10-22", + "validated-manual:lab:state-twolayer@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ], + "notes": "F6: `squad_state_health` answered \"State backend storage: StateBackendStorageAdapter\" instead of the backend name the digest promises." + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`squad init|upgrade --state-backend`; state-mcp resolves the backend from `config.json`; digest Β§16 requires `squad_state_health` before writes and halts without the bridge.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::R3-9: createMcpBackend honors a configured (non-local) state backend instead of writing .squad/backend", + "validated-test:test/state-backend.test.ts::*", + "validated-test:test/upgrade-state-backend.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree" + ] + } + } + }, + { + "id": "skills-precedence", + "name": "Skills (5 roots, precedence, untrusted-data rule)", + "area": "Core", + "docs": [ + "features/skills" + ], + "canonicalSections": [ + "Team Mode" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "validated-manual:lab:skills-precedence@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "validated-manual:lab:skills-precedence@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§17 lists `.squad/skills/` β†’ `.copilot/skills/` β†’ `.github/skills/` β†’ `.claude/skills/` β†’ `.agents/skills/` with earlier-wins precedence.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/skills.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "reviewer-lockout", + "name": "Reviewer rejection protocol & strict author lockout", + "area": "Quality", + "docs": [ + "features/reviewer-protocol" + ], + "canonicalSections": [ + "Reviewer Rejection Protocol" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:reviewer-lockout@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:reviewer-lockout@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§12: REJECT locks out the author; revision reassigned; re-review required.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "rai", + "name": "Rai β€” Responsible-AI reviewer (🟒/🟑/πŸ”΄)", + "area": "Quality", + "docs": [ + "features/reviewer-protocol" + ], + "canonicalSections": [ + "Rai β€” RAI Reviewer" + ], + "dependsOn": [ + "b", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Canonical Β§Rai; background by default.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§13; background capable.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§13; runs synchronously where `background-runs` is absent (see background-agents).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "fact-checker", + "name": "Fact Checker β€” verification & devil's advocate", + "area": "Quality", + "docs": [ + "features/reviewer-protocol" + ], + "canonicalSections": [ + "Fact Checker β€” Verification & Devil's Advocate" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§14 with βœ…/⚠️/❌/πŸ” ratings, steelman and pre-mortem.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "ceremonies", + "name": "Ceremonies (before/after/manual, cooldowns)", + "area": "Advanced", + "docs": [ + "features/ceremonies" + ], + "canonicalSections": [ + "Ceremonies" + ], + "dependsOn": [ + "b", + "c" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§15 reads `ceremonies.md`, spawns a facilitator, records via `squad_decide`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "human-members", + "name": "Human team members (never spawned; routed as requests)", + "area": "Advanced", + "docs": [ + "features/human-team-members", + "scenarios/team-of-humans" + ], + "canonicalSections": [ + "Team Mode" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§21.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "copilot-coding-agent", + "name": "@copilot coding agent member (`squad copilot`, GitHub assignment)", + "area": "GitHub", + "docs": [ + "features/copilot-coding-agent" + ], + "canonicalSections": [ + "Copilot Coding Agent Member" + ], + "dependsOn": [ + "a", + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI toggles the member; digest Β§21 says never spawn it, review its PRs. Assignment happens on GitHub, independent of the local host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/team-capabilities-lifecycle.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "ralph-coordinator-loop", + "name": "Ralph β€” interactive work monitor (\"Ralph, go\")", + "area": "GitHub", + "docs": [ + "features/ralph" + ], + "canonicalSections": [ + "Ralph β€” Work Monitor" + ], + "dependsOn": [ + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:ralph-no-repo@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:ralph-no-repo@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9: coordinator runs the loop itself via `gh`; circuit breaker template. Requires `gh` authenticated inside the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "ralph-cli-triage-watch", + "name": "Ralph CLI (`squad triage` / `watch` / `loop` --execute)", + "area": "GitHub", + "docs": [ + "features/ralph", + "features/labels" + ], + "dependsOn": [ + "a", + "e" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Default `agentCmd` is the Copilot CLI (`copilot -p …`).", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "validated-test:test/ralph-monitor.test.ts::*", + "validated-test:test/watch-fleet-dispatch.test.ts::*" + ] + }, + "claude": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd \" … {prompt}\"`) is configured; no built-in preset for this host.", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ] + }, + "kiro": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd \" … {prompt}\"`) is configured; no built-in preset for this host.", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd \" … {prompt}\"`) is configured; no built-in preset for this host.", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ] + }, + "cursor": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd \" … {prompt}\"`) is configured; no built-in preset for this host.", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd \" … {prompt}\"`) is configured; no built-in preset for this host.", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "degraded", + "validation": "validated-test", + "mechanism": "Scanning/routing is host-agnostic, but `--execute` dispatches through the Copilot CLI unless `agentCmd` (`--agent-cmd \" … {prompt}\"`) is configured; no built-in preset for this host.", + "evidence": [ + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "prd-mode", + "name": "PRD mode (decompose β†’ approve β†’ dependency-aware dispatch)", + "area": "Advanced", + "docs": [ + "features/prd-mode" + ], + "canonicalSections": [ + "PRD Mode" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§19; `prd-intake.md` template on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "github-issues-mode", + "name": "GitHub Issues mode (connect, list, route, branch β†’ PR β†’ merge)", + "area": "GitHub", + "docs": [ + "features/github-issues", + "concepts/github-workflow", + "scenarios/issue-driven-dev" + ], + "canonicalSections": [ + "GitHub Issues Mode" + ], + "dependsOn": [ + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:github-issues-readonly@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-manual:lab:github-issues-readonly@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§18 with `gh` prerequisites, `squad/{issue}-{slug}` branches, `gh pr create`; `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "labels-triage", + "name": "Labels & triage (`squad` / `squad:` taxonomy)", + "area": "GitHub", + "docs": [ + "features/labels" + ], + "canonicalSections": [ + "GitHub Issues Mode", + "Ralph β€” Work Monitor" + ], + "dependsOn": [ + "a", + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "validated-manual:lab:github-issues-readonly@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "validated-manual:lab:github-issues-readonly@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 route by `squad:` labels; CLI triage applies the same taxonomy.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/ralph-triage.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "project-boards", + "name": "Project boards (`squad triage --board`)", + "area": "GitHub", + "docs": [ + "features/project-boards" + ], + "dependsOn": [ + "a", + "e" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI capability, GitHub Projects via `gh`; the local host is not involved.", + "evidence": [ + "validated-test:test/ralph-board.test.ts::*" + ] + } + } + }, + { + "id": "gitlab-issues", + "name": "GitLab Issues mode (experimental, `glab`)", + "area": "Platforms", + "docs": [ + "features/gitlab-issues" + ], + "dependsOn": [ + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Docs-only: no `gitlab` PlatformType in the SDK, no `glab` path in `squad triage|watch`, and neither the canonical agent nor the digest has a GitLab section. Works only if the model follows the docs page ad hoc with `glab`.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F2. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "azure-devops", + "name": "Azure DevOps platform (work items, PRs, `az boards`, ADO MCP)", + "area": "Platforms", + "docs": [ + "features/enterprise-platforms" + ], + "canonicalSections": [ + "GitHub Issues Mode" + ], + "dependsOn": [ + "a", + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "`squad triage|watch` auto-detect ADO from the remote (or `config.platform: azure-devops`) and use `az`; `squad upgrade` seeds an `EXAMPLE-azure-devops` MCP server in `.mcp.json`. The coordinator section is GitHub-only (`gh`); ADO commands exist only in `issue-lifecycle.md`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3: interactive Issues mode has no ADO branch in the prompt. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-manual:lab:ado-platform@2026-10-22", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3. Live: detected ADO from the remote, read `issue-lifecycle.md`, proposed `az boards` commands, noted the template has no backlog-list command. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-manual:lab:ado-platform@2026-10-22", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3. Live: detected ADO from the remote, read `issue-lifecycle.md`, proposed `az boards` commands, noted the template has no backlog-list command. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI triage/watch on ADO is host-agnostic. In-host Issues mode: digest Β§18 is `gh`-only and the ADO MCP example is only seeded into Copilot's `.mcp.json`; ADO commands reachable only via `issue-lifecycle.md` on demand.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F3. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "upstream-inheritance", + "name": "Upstream inheritance (`squad upstream add|sync`, inherited skills/decisions/wisdom/routing)", + "area": "Multi-squad", + "docs": [ + "features/upstream-inheritance" + ], + "dependsOn": [ + "a", + "b" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-manual:lab:upstream@2026-10-22", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. Live (Claude): found both upstream decision and skill, but only because the prompt pointed at `upstream.json`. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-manual:lab:upstream@2026-10-22", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. Live (OpenCode, partial): found the upstream decision but missed `.copilot/skills/org-logging` (outside the `.squad/` the upstream points at), which `resolveUpstreams()` would have returned. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI config/clone/sync is host-agnostic and tested. Runtime inheritance is not wired: `resolveUpstreams()` has no CLI/MCP caller, and neither the canonical agent nor the digest tells the coordinator to read `upstream.json` (only the `cross-squad` skill mentions it).", + "evidence": [ + "validated-test:test/upstream.test.ts::*", + "validated-test:test/upstream-e2e.test.ts::*", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F1: docs promise \"coordinator reads upstreams at session start\" but no prompt/CLI path implements it on any host. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "cross-squad-registry", + "name": "Multiple squads / cross-squad (`squad registry|discover|delegate`, cross-squad skills)", + "area": "Multi-squad", + "docs": [ + "scenarios/multiple-squads" + ], + "canonicalSections": [ + "Team Mode" + ], + "dependsOn": [ + "a", + "b", + "e" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "validated-manual:lab:cross-squad@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "validated-manual:lab:cross-squad@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§20 routes peer-squad requests through the `cross-squad` / `cross-squad-communication` skills; CLI registry + delegate (GitHub issue handoff via `gh`).", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "validated-test:test/cross-squad-registry.test.ts::*", + "validated-test:test/cross-squad.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "subsquads", + "name": "SubSquads / workstreams (`squad subsquads`, multi-Codespace)", + "area": "Multi-squad", + "docs": [ + "scenarios/multi-codespace", + "scenarios/scaling-workstreams", + "features/streams" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI + watch discovery; host not involved.", + "evidence": [ + "validated-test:test/watch-subsquad-discovery.test.ts::*" + ] + } + } + }, + { + "id": "monorepo-team-root", + "name": "Monorepo / team-root resolution (`--team-root`, `SQUAD_TEAM_ROOT`, launch from a subfolder)", + "area": "Multi-squad", + "docs": [ + "scenarios/monorepo", + "features/worktrees" + ], + "canonicalSections": [ + "State & Team Root Resolution (before mode check)" + ], + "dependsOn": [ + "a", + "b", + "c", + "d" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI honours `--team-root`/`SQUAD_TEAM_ROOT`; state-mcp walks up from cwd (`findSquadDir`); canonical Β§State & Team Root Resolution + `worktree-reference.md` resolve `TEAM_ROOT` and pass it to every spawn.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "Claude discovers `.claude/agents/squad.md` and `.mcp.json` from a package subfolder; state-mcp walks up to the root `.squad/`. Headless (`-p`) runs need `--mcp-config /.mcp.json` or a prior per-project approval (F5).", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-manual:lab:mono-subfolder@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/squad-20-host-feature-matrix.test.ts::claude lists the root .mcp.json squad_state server from packages/api", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Validate per host: does the host find root-level projections from a subfolder cwd? Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Validate per host: does the host find root-level projections from a subfolder cwd? Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "OpenCode resolves `opencode.json` (agent + MCP) from the repo root when launched in a package subfolder; state-mcp walks up to the root `.squad/`.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-manual:lab:mono-subfolder@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/squad-20-host-feature-matrix.test.ts::opencode resolves the squad primary agent and the squad_state MCP entry from packages/api", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Validate per host: does the host find root-level projections from a subfolder cwd? Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Validate per host: does the host find root-level projections from a subfolder cwd? Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Validate per host: does the host find root-level projections from a subfolder cwd? No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI/MCP resolution is host-agnostic, but the digest has no team-root section (only `worktree-reference.md` on demand) and the host discovers its projected agent/MCP config from its own project root, so launching from a package subfolder may not load the Squad coordinator at all.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp resolves the root .squad when launched from a monorepo subfolder", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Validate per host: does the host find root-level projections from a subfolder cwd? Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "dual-root-remote-mode", + "name": "Dual-root remote mode (`squad init --mode remote`, `link`, `externalize` / `internalize`)", + "area": "Multi-squad", + "docs": [ + "features/dual-mode-deployment", + "scenarios/team-state-storage" + ], + "canonicalSections": [ + "State & Team Root Resolution (before mode check)" + ], + "dependsOn": [ + "a", + "b", + "c" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI writes `config.json.teamRoot`; state-mcp resolves `mode: remote`; canonical step 3 loads `team.md` from the team root.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "The state bridge follows `config.json.teamRoot`, so the host coordinator read the team-root roster via `squad_state_read` and did not enter Init Mode, even though the digest has no team-root section.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-manual:lab:satellite-remote@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Live: roster served from `..\\base`; no casting attempted. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F4 candidate β€” validate. Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "The state bridge follows `config.json.teamRoot`, so the host coordinator read the team-root roster via `squad_state_read` and did not enter Init Mode, even though the digest has no team-root section.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-manual:lab:satellite-remote@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Live: roster served from `..\\base`; no casting attempted. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The runtime path works (state-mcp walks up to the root `.squad/` / follows `teamRoot`; see the live run where recorded), but the projected digest carries no team-root section, so the coordinator is not told how resolution works. Unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F4 candidate β€” validate. Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F4 candidate β€” validate. No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "State tools follow `teamRoot` transparently, but the digest reads `.squad/team.md` literally and never mentions `teamRoot`/`stateLocation`, so a satellite repo may look like Init Mode to the host coordinator.", + "evidence": [ + "validated-test:test/resolution.test.ts::*", + "validated-test:test/squad-20-host-feature-matrix.test.ts::state-mcp follows config.json teamRoot from a satellite repo (remote mode)", + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Finding F4 candidate β€” validate. Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "git-worktrees", + "name": "Git worktrees & worktree mode (issue worktrees, `WORKTREE_PATH`)", + "area": "Advanced", + "docs": [ + "features/worktrees" + ], + "canonicalSections": [ + "Team Mode" + ], + "dependsOn": [ + "a", + "b", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "validated-manual:lab:worktree-spawn@2026-10-22" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "validated-manual:lab:worktree-spawn@2026-10-22" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§9/Β§18 prefer an isolated worktree per issue and point to `worktree-reference.md`; needs shell access in the host.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator Ralph mode", + "validated-test:test/worktree.test.ts::*", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "export-import", + "name": "Export / import (`squad export`, `squad import`, team portability)", + "area": "Advanced", + "docs": [ + "features/export-import", + "scenarios/team-portability", + "concepts/portability" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; portable `clients[]` hygiene strips host secrets.", + "evidence": [ + "validated-test:test/cli/export-import.test.ts::*", + "validated-test:test/clients.test.ts::portable clients[] hygiene" + ] + } + } + }, + { + "id": "storage-provider", + "name": "Storage provider abstraction (FS / SQLite / external state)", + "area": "Infrastructure", + "docs": [ + "features/storage-provider" + ], + "dependsOn": [ + "a", + "c" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "SDK/CLI layer under state-mcp; host not involved.", + "evidence": [ + "validated-test:test/state-backend.test.ts::*" + ] + } + } + }, + { + "id": "notifications", + "name": "Notifications (`watch --notify-level`, Teams/email monitors)", + "area": "Infrastructure", + "docs": [ + "features/notifications" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI watch capability.", + "evidence": [ + "validated-test:test/watch-notify-level.test.ts::*" + ] + } + } + }, + { + "id": "marketplace-plugins", + "name": "Marketplace & plugins (`squad plugin marketplace …`, skill install on cast)", + "area": "Advanced", + "docs": [ + "features/marketplace", + "features/plugins" + ], + "canonicalSections": [ + "Team Mode" + ], + "dependsOn": [ + "a", + "b" + ], + "cells": { + "copilot": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI + canonical \"check plugin marketplaces when adding a member\" step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): The CLI/SDK side works, but the projected digest carries no section for it, so the coordinator is not told about it on this host. Unsupported on this host until the section ships." + }, + "claude": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI works; the digest Init/cast flow does not include the marketplace-browse step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "kiro": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI works; the digest Init/cast flow does not include the marketplace-browse step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "opencode": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI works; the digest Init/cast flow does not include the marketplace-browse step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "cursor": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI works; the digest Init/cast flow does not include the marketplace-browse step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "codex": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI works; the digest Init/cast flow does not include the marketplace-browse step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + }, + "antigravity": { + "capability": "unsupported", + "validation": "validated-test", + "expectedFailure": true, + "mechanism": "CLI works; the digest Init/cast flow does not include the marketplace-browse step.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator digest vs. host feature matrix", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine. Expected-fail digest gap (per-host it.fails in test/clients.test.ts): unsupported on this host until the section ships." + } + } + }, + { + "id": "mcp-integration", + "name": "MCP integration (user MCP servers discovered; MCP β†’ CLI fallback)", + "area": "Advanced", + "docs": [ + "features/mcp" + ], + "canonicalSections": [ + "MCP Integration" + ], + "dependsOn": [ + "b", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "static-only", + "mechanism": "Canonical Β§MCP Integration with tool-prefix discovery and `gh`/`az` fallbacks; `.mcp.json`.", + "evidence": [ + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Host loads its own MCP config; `squad_state` is merged without clobbering user servers. Digest lacks the discovery/fallback table but hosts expose MCP tools natively.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "standalone-install", + "name": "Standalone install (no npm; `squad.exe state-mcp` launch spec)", + "area": "Core", + "docs": [ + "features/standalone-install" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`mcp-spec.ts` picks the standalone binary for the state-mcp launch spec in every projection.", + "evidence": [ + "validated-test:test/cli/upgrade.test.ts::*" + ] + } + } + }, + { + "id": "vscode", + "name": "VS Code (`runSubagent`, settings default agent)", + "area": "Core", + "docs": [ + "features/vscode" + ], + "canonicalSections": [ + "Client Compatibility" + ], + "dependsOn": [ + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Canonical Β§Client Compatibility micro-playbook; `squad init` writes `.vscode/settings.json`.", + "evidence": [ + "validated-test:test/cli/init.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Copilot-specific surface.", + "evidence": [ + "static-only" + ] + }, + "kiro": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Copilot-specific surface.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Copilot-specific surface.", + "evidence": [ + "static-only" + ] + }, + "cursor": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Copilot-specific surface.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Copilot-specific surface.", + "evidence": [ + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Copilot-specific surface.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "squad-rc-start", + "name": "Squad RC / `squad start` (remote control bridge, tunnels)", + "area": "Advanced", + "docs": [ + "features/squad-rc", + "scenarios/remote-qa" + ], + "dependsOn": [ + "a", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`squad start|rc` wrap the Copilot CLI with phone/browser access.", + "evidence": [ + "validated-test:test/cli/rc.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped.", + "evidence": [ + "static-only" + ] + }, + "kiro": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped.", + "evidence": [ + "static-only" + ] + }, + "cursor": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped.", + "evidence": [ + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Bridges the Copilot CLI (ACP stdio); other hosts are not wrapped.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "enterprise-platforms", + "name": "Enterprise platforms (ADO + Planner work items, Teams/ADO discussions)", + "area": "Infrastructure", + "docs": [ + "features/enterprise-platforms" + ], + "dependsOn": [ + "a", + "e" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Platform adapters in `@bradygaster/squad-sdk/platform`, consumed by `squad triage|watch`.", + "evidence": [ + "validated-test:test/platform-adapter.test.ts::*", + "validated-test:test/ralph-commands.test.ts::*" + ] + } + } + }, + { + "id": "distributed-mesh", + "name": "Distributed mesh, capability routing, rate limiting, KEDA autoscaling", + "area": "Infrastructure", + "docs": [ + "features/distributed-mesh", + "features/capability-routing", + "features/rate-limiting", + "features/keda-scaling" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Fleet/watch-side features; the interactive host is not involved.", + "evidence": [ + "validated-test:test/watch-fleet-dispatch.test.ts::*", + "validated-test:test/rate-limiting.test.ts::*", + "validated-test:test/watch-rate-limit.test.ts::*" + ] + } + } + }, + { + "id": "aspire-dashboard", + "name": "Aspire dashboard / OTel observability (`squad aspire`)", + "area": "Infrastructure", + "docs": [ + "scenarios/aspire-dashboard", + "scenarios/production-observability" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "CLI launches the dashboard; OTel export from the SDK runtime.", + "evidence": [ + "validated-test:test/aspire-command.test.ts::*", + "validated-test:test/otel-export.test.ts::*" + ] + } + } + }, + { + "id": "gh-aw", + "name": "GitHub Agentic Workflows (gh-aw) integration", + "area": "GitHub", + "docs": [ + "guide/gh-aw" + ], + "dependsOn": [ + "e" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Workflows in `workflows/*.md`; verifier + e2e scripts.", + "evidence": [ + "validated-test:test/gh-aw-enlistment-skill.test.ts::*", + "static-only" + ] + }, + "claude": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Runs in GitHub Actions with the Copilot engine; the local host is irrelevant.", + "evidence": [ + "static-only" + ] + }, + "kiro": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Runs in GitHub Actions with the Copilot engine; the local host is irrelevant.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Runs in GitHub Actions with the Copilot engine; the local host is irrelevant.", + "evidence": [ + "static-only" + ] + }, + "cursor": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Runs in GitHub Actions with the Copilot engine; the local host is irrelevant.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Runs in GitHub Actions with the Copilot engine; the local host is irrelevant.", + "evidence": [ + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "n/a", + "validation": "static-only", + "mechanism": "Runs in GitHub Actions with the Copilot engine; the local host is irrelevant.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "sdk-first-mode", + "name": "SDK-first mode (`squad.config.ts`, `squad build`, `squad migrate`)", + "area": "Core", + "docs": [ + "sdk-first-mode", + "reference/sdk" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Compiles to the same `.squad/` markdown every host consumes.", + "evidence": [ + "validated-test:test/migrate.test.ts::*" + ] + } + } + }, + { + "id": "doctor-health-nap", + "name": "Maintenance CLIs (`squad doctor`, `squad health`, `squad nap`, `squad upgrade`)", + "area": "Core", + "docs": [ + "reference/cli", + "scenarios/upgrading", + "scenarios/troubleshooting" + ], + "dependsOn": [ + "a" + ], + "hostIndependent": true, + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Pure CLI; `upgrade --client` refreshes every configured host projection.", + "evidence": [ + "validated-test:test/cli/doctor.test.ts::*", + "validated-test:test/cli/upgrade.test.ts::*", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::RC1β†’stable exit 1: upgrade and rollback from a v0.1 workspace" + ] + } + } + }, + { + "id": "client-projection", + "name": "Squad 2.0 `--client` projection (coordinator file + MCP config per host, rollback)", + "area": "Squad 2.0", + "docs": [ + "concepts/squad-2-0-architecture", + "scenarios/using-squad-across-clients", + "scenarios/client-compatibility" + ], + "dependsOn": [ + "a", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts", + "validated-test:test/clients-real-cli.test.ts::claude discovers the squad subagents and parses .mcp.json" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts", + "validated-test:test/clients-real-cli.test.ts::kiro validates and lists the squad agent" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts", + "validated-test:test/clients-real-cli.test.ts::opencode loads squad as a primary agent and connects the MCP server" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts", + "validated-test:test/clients-real-cli.test.ts::cursor-agent lists the squad_state server from .cursor/mcp.json (read-only)" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts", + "validated-test:test/clients-real-cli.test.ts::codex loads the project config (trusted), sees squad_state MCP, discovers the squad TOML role, and activates coordinator instructions on spawn" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`installClients()` writes host-native files idempotently; real CLIs load them.", + "evidence": [ + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 1: client projections and --client", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients.test.ts::Reviewer gate (@Bubu): /client <-> /clients export identity (===), pure projection boundary, and byte-exact rollback across all 7 hosts", + "validated-test:test/clients-real-cli.test.ts::antigravity discovers the squad agent" + ] + } + } + }, + { + "id": "squad-state-mcp-bridge", + "name": "`squad_state` MCP bridge reachable from the host (stdio, host-prefixed tool names)", + "area": "Squad 2.0", + "docs": [ + "concepts/squad-2-0-architecture", + "reference/tools-and-hooks" + ], + "dependsOn": [ + "c", + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients-real-cli.test.ts::claude discovers the squad subagents and parses .mcp.json", + "validated-manual:lab:smoke-roster@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::claude --agent squad reads the roster through mcp__squad_state__squad_state_read" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients-real-cli.test.ts::kiro validates and lists the squad agent", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients-real-cli.test.ts::opencode loads squad as a primary agent and connects the MCP server", + "validated-manual:lab:smoke-roster@2026-10-22", + "validated-test:test/squad-20-host-feature-matrix.test.ts::opencode --agent squad reads the roster through squad_state_squad_state_read" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients-real-cli.test.ts::cursor-agent lists the squad_state server from .cursor/mcp.json (read-only)", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients-real-cli.test.ts::codex loads the project config (trusted), sees squad_state MCP, discovers the squad TOML role, and activates coordinator instructions on spawn", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Projected launch spec `npx -y @bradygaster/squad-cli@ state-mcp` (or standalone binary); digest Β§4 documents the host prefixes.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::executes squad_state tools against the workspace .squad directory", + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::writes the host config and agent files each client reads", + "validated-test:test/clients-real-cli.test.ts::antigravity discovers the squad agent", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "capability-negotiation", + "name": "Capability negotiation (client ∩ backend ∩ policy)", + "area": "Squad 2.0", + "docs": [ + "concepts/squad-2-0-architecture" + ], + "dependsOn": [ + "c" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "`CAPABILITY_TOKENS_BY_HOST` 1:1 with `capability-matrix.json`; negotiated over real JSON-RPC.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::negotiates capabilities for the client per capability-matrix.json", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::12. capability tokens match capability-matrix.json for all 7 hosts", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 2: cross-plane capability intersection" + ] + } + } + }, + { + "id": "experimental-backend", + "name": "Experimental conversation backend (`squad_backend_*`, durable-http, approvals, resume)", + "area": "Squad 2.0", + "docs": [ + "concepts/squad-2-0-architecture" + ], + "dependsOn": [ + "c" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Opt-in tools over the same MCP server; backend semantics are host-independent.", + "evidence": [ + "validated-test:test/squad-20-real-clients-stdio.e2e.test.ts::completes the MCP handshake and lists squad_state_* and all squad_backend_* tools when opted in", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Scenario 4: DurableHttpSquadBackend full HTTP lifecycle", + "validated-test:test/squad-20-all-scenarios.e2e.test.ts::Full non-bypass journey: host adapter β†’ broker β†’ harness β†’ approval β†’ restart/reconnect" + ] + } + } + }, + { + "id": "process-hygiene", + "name": "Process hygiene (never kill by image name; PID-only)", + "area": "Core", + "docs": [ + "scenarios/troubleshooting" + ], + "canonicalSections": [ + "Constraints" + ], + "dependsOn": [ + "b" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "kiro": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ] + }, + "cursor": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "supported", + "validation": "validated-test", + "mechanism": "Digest Β§22–23.", + "evidence": [ + "validated-test:test/clients.test.ts::coordinator behavioral-contract parity", + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + }, + { + "id": "subagent-mcp-inheritance", + "name": "Specialists (subagents) can reach `squad_state` tools themselves", + "area": "Squad 2.0", + "docs": [ + "concepts/squad-2-0-architecture" + ], + "dependsOn": [ + "d" + ], + "cells": { + "copilot": { + "capability": "supported", + "validation": "static-only", + "mechanism": "`task` subagents inherit the session MCP servers.", + "evidence": [ + "static-only" + ] + }, + "claude": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents).", + "evidence": [ + "validated-manual:lab:parallel-fanout@2026-10-22" + ], + "notes": "Live: Galois/Fermat/Scribe each called `squad_state_*` tools from inside their spawn (history appended, inbox drained)." + }, + "kiro": { + "capability": "supported", + "validation": "blocked", + "blockedReason": "live run blocked on the reference machine: kiro-cli chat failed: \"The monthly usage limit has been reached\".", + "mechanism": "Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents).", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: kiro quota/usage limit reached on the reference machine." + }, + "opencode": { + "capability": "supported", + "validation": "validated-live", + "mechanism": "Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents).", + "evidence": [ + "validated-manual:lab:parallel-fanout@2026-10-22" + ], + "notes": "Live: Galois/Fermat/Scribe each called `squad_state_*` tools from inside their spawn (history appended, inbox drained)." + }, + "cursor": { + "capability": "supported", + "validation": "blocked", + "blockedReason": "live run blocked on the reference machine: cursor-agent -p failed: \"You've hit your usage limit\".", + "mechanism": "Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents).", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: cursor quota/usage limit reached on the reference machine." + }, + "codex": { + "capability": "supported", + "validation": "untested", + "mechanism": "Subagents inherit MCP servers (Claude `Task`, Codex `spawn_agent`, OpenCode child sessions, Kiro subagents).", + "evidence": [ + "static-only" + ], + "notes": "No Codex binary or ChatGPT/API auth on the reference machine; static-only." + }, + "antigravity": { + "capability": "degraded", + "validation": "blocked", + "blockedReason": "live run blocked on the reference machine: agy -p failed: RESOURCE_EXHAUSTED 429 \"Individual quota reached\" (resets in ~75h).", + "mechanism": "`invoke_subagent` starts with a clean context; MCP attached via agent frontmatter may not propagate β€” specialists return results for the coordinator to persist.", + "evidence": [ + "static-only" + ], + "notes": "Live run blocked on 2026-10-22: antigravity quota/usage limit reached on the reference machine." + } + } + } + ], + "liveRuns": [ + { + "host": "claude", + "scenario": "smoke-roster", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_read" + ], + "notes": "Roster + testing owner from team.md/routing.md via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion)." + }, + { + "host": "claude", + "scenario": "init-mode", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_read", + "Bash" + ], + "notes": "Empty roster β†’ proposed 4 specialists, cast each with `squad cast --name`, stopped after reporting the roster." + }, + { + "host": "claude", + "scenario": "upstream", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_read", + "Bash" + ], + "notes": "Found SEVEN-SECOND-TIMEOUT decision and ORG-LOG-PREFIX skill by reading the upstream path from upstream.json." + }, + { + "host": "claude", + "scenario": "cross-squad", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Read", + "Bash" + ], + "notes": "Loaded cross-squad + cross-squad-communication skills, read squad-registry.json and peer manifest, prepared `squad delegate peer-b …`, no issue created, no ad-hoc subagents." + }, + { + "host": "claude", + "scenario": "mono-subfolder", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_read" + ], + "notes": "From packages/api with --mcp-config /.mcp.json; natively the server is \"Pending approval\" (F5)." + }, + { + "host": "claude", + "scenario": "satellite-remote", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_read", + "Read" + ], + "notes": "Roster served from teamRoot ..\\base; no Init Mode." + }, + { + "host": "claude", + "scenario": "ado-platform", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash", + "Read" + ], + "notes": "Detected Azure DevOps from the remote; consulted issue-lifecycle.md; proposed az boards/az repos commands; ran only read-only checks." + }, + { + "host": "claude", + "scenario": "github-issues-readonly", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash", + "mcp__squad_state__squad_state_read" + ], + "notes": "gh prerequisites checked; 5 squad-labelled issues listed read-only and routed via routing.md (Lead triages unknown squad:* labels)." + }, + { + "host": "claude", + "scenario": "state-orphan", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_health", + "mcp__squad_state__squad_decide", + "mcp__squad_state__squad_state_list" + ], + "notes": "Decision committed to the squad-state orphan branch; working tree untouched; health reported the storage class, not \"orphan\" (F6)." + }, + { + "host": "claude", + "scenario": "state-twolayer", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_state_health", + "mcp__squad_state__squad_decide", + "mcp__squad_state__squad_state_list" + ], + "notes": "Decision committed to the squad-state branch (two-layer); health reported the storage class, not \"two-layer\" (F6)." + }, + { + "host": "claude", + "scenario": "skills-precedence", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash" + ], + "notes": ".squad/skills/deploy-rules (DEPLOY-ALPHA) won over .github and .claude copies; no spawn in the dry run." + }, + { + "host": "claude", + "scenario": "directive-capture", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "mcp__squad_state__squad_decide" + ], + "notes": "Persistent \"always use tabs\" directive recorded via squad_decide and acknowledged." + }, + { + "host": "claude", + "scenario": "reviewer-lockout", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Agent", + "mcp__squad_state__squad_decide" + ], + "notes": "Galois authored, Fermat REJECTed (\"missing tests\"), Galois locked out, revision assigned to Noether, verdict recorded via squad_decide." + }, + { + "host": "claude", + "scenario": "ralph-no-repo", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash" + ], + "notes": "No git remote β†’ Ralph reported it and stopped without routing work." + }, + { + "host": "claude", + "scenario": "worktree-spawn", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash", + "Read" + ], + "notes": "Created sibling worktree base-12 on squad/12-add-health per worktree-reference.md." + }, + { + "host": "claude", + "scenario": "parallel-fanout", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Agent", + "mcp__squad_state__squad_state_append", + "mcp__squad_state__squad_state_health" + ], + "notes": "Two specialists spawned in one turn (Claude: background subagents), each appended its own history via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion); Scribe drained the inbox." + }, + { + "host": "opencode", + "scenario": "smoke-roster", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_state_read" + ], + "notes": "Roster + testing owner from team.md/routing.md via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion)." + }, + { + "host": "opencode", + "scenario": "init-mode", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_state_read", + "Bash" + ], + "notes": "Empty roster β†’ proposed 4 specialists, cast each with `squad cast --name`, stopped after reporting the roster." + }, + { + "host": "opencode", + "scenario": "upstream", + "date": "2026-10-22", + "outcome": "partial", + "observedTools": [ + "squad_state_squad_state_read", + "Bash" + ], + "notes": "Found the upstream decision; missed the `.copilot/skills` skill living beside the upstream `.squad/`." + }, + { + "host": "opencode", + "scenario": "cross-squad", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Read", + "Bash" + ], + "notes": "Loaded cross-squad + cross-squad-communication skills, read squad-registry.json and peer manifest, prepared `squad delegate peer-b …`, no issue created, no ad-hoc subagents." + }, + { + "host": "opencode", + "scenario": "mono-subfolder", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_state_read" + ], + "notes": "From packages/api; opencode.json and agent resolved from the repo root." + }, + { + "host": "opencode", + "scenario": "satellite-remote", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_state_read", + "Read" + ], + "notes": "Roster served from teamRoot ..\\base; no Init Mode." + }, + { + "host": "opencode", + "scenario": "ado-platform", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash", + "Read" + ], + "notes": "Detected Azure DevOps from the remote; consulted issue-lifecycle.md; proposed az boards/az repos commands; ran only read-only checks." + }, + { + "host": "opencode", + "scenario": "github-issues-readonly", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash", + "squad_state_squad_state_read" + ], + "notes": "gh prerequisites checked; 5 squad-labelled issues listed read-only and routed via routing.md (Lead triages unknown squad:* labels)." + }, + { + "host": "opencode", + "scenario": "state-orphan", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_state_health", + "squad_state_squad_decide", + "squad_state_squad_state_list" + ], + "notes": "Decision committed to the squad-state orphan branch; working tree untouched; health reported the storage class, not \"orphan\" (F6)." + }, + { + "host": "opencode", + "scenario": "state-twolayer", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_state_health", + "squad_state_squad_decide", + "squad_state_squad_state_list" + ], + "notes": "Decision committed to the squad-state branch (two-layer); health reported the storage class, not \"two-layer\" (F6)." + }, + { + "host": "opencode", + "scenario": "skills-precedence", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash" + ], + "notes": ".squad/skills/deploy-rules (DEPLOY-ALPHA) won over .github and .claude copies; no spawn in the dry run." + }, + { + "host": "opencode", + "scenario": "directive-capture", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "squad_state_squad_decide" + ], + "notes": "Persistent \"always use tabs\" directive recorded via squad_decide and acknowledged." + }, + { + "host": "opencode", + "scenario": "reviewer-lockout", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "task", + "squad_state_squad_decide" + ], + "notes": "Galois authored, Fermat REJECTed (\"missing tests\"), Galois locked out, revision assigned to Noether, verdict recorded via squad_decide." + }, + { + "host": "opencode", + "scenario": "ralph-no-repo", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash" + ], + "notes": "No git remote β†’ Ralph reported it and stopped without routing work." + }, + { + "host": "opencode", + "scenario": "worktree-spawn", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "Bash", + "Read" + ], + "notes": "Created sibling worktree base-12 on squad/12-add-health per worktree-reference.md." + }, + { + "host": "opencode", + "scenario": "parallel-fanout", + "date": "2026-10-22", + "outcome": "pass", + "observedTools": [ + "task", + "squad_state_squad_state_append", + "squad_state_squad_state_health" + ], + "notes": "Two specialists spawned in one turn (Claude: background subagents), each appended its own history via host-reported squad_state tool events (observed in the host transcript, not a JSON-RPC assertion); Scribe drained the inbox." + }, + { + "host": "kiro", + "scenario": "smoke-roster", + "date": "2026-10-22", + "outcome": "blocked", + "observedTools": [], + "notes": "kiro-cli chat failed: \"The monthly usage limit has been reached\"." + }, + { + "host": "antigravity", + "scenario": "smoke-roster", + "date": "2026-10-22", + "outcome": "blocked", + "observedTools": [], + "notes": "agy -p failed: RESOURCE_EXHAUSTED 429 \"Individual quota reached\" (resets in ~75h)." + }, + { + "host": "cursor", + "scenario": "smoke-roster", + "date": "2026-10-22", + "outcome": "blocked", + "observedTools": [], + "notes": "cursor-agent -p failed: \"You've hit your usage limit\"." + } + ], + "expectedFailures": [ + { + "featureId": "monorepo-team-root", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): team-root resolution (teamRoot / stateLocation / TEAM_ROOT)", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + }, + { + "featureId": "dual-root-remote-mode", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): team-root resolution (teamRoot / stateLocation / TEAM_ROOT)", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + }, + { + "featureId": "upstream-inheritance", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): upstream inheritance (upstream.json)", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + }, + { + "featureId": "azure-devops", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): Azure DevOps issue tracking (az boards / ADO)", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + }, + { + "featureId": "gitlab-issues", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): GitLab issue tracking (glab)", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + }, + { + "featureId": "model-selection", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): per-agent model / reasoning / context-tier selection", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + }, + { + "featureId": "marketplace-plugins", + "test": "test/clients.test.ts::digest gap (expected until the stack adds it): plugin marketplace browse on cast", + "kind": "it.fails", + "perHost": true, + "hosts": [ + "copilot", + "claude", + "kiro", + "opencode", + "cursor", + "codex", + "antigravity" + ], + "meaning": "The projected digest lacks this canonical section on the listed hosts; one it.fails per host (title suffixed `[]`) turns red the moment a stack adds it. Every listed cell is `unsupported` for that host until then." + } + ], + "limitations": [ + "Capability and validation are separate axes: a `supported` cell may be only `static-only`, and an `unsupported` digest-gap cell is `validated-test` because an `it.fails` proves the gap. Read both columns.", + "Expected failures are pinned per host and per gap (one `it.fails` per ` []` pair); a section landing for one host turns exactly that host's test red. Those cells are `unsupported`, never `degraded`.", + "Live evidence exists for Claude Code and OpenCode only (reference machine, 2026-10-22). Kiro, Codex, Antigravity and Cursor have no passing live run: their cells are `validated-test` only through host-independent tests, otherwise `static-only`, `untested` or `blocked`.", + "The opt-in headless coordinator tests (`SQUAD_REAL_MODEL_TESTS=1`) verify the MCP bridge through a tee'd `squad state-mcp` transcript (a successful `tools/call` of `squad_state_read` with `key: \"team.md\"`), not by matching stdout. No other cell claims bridge-level verification." + ] +} diff --git a/test/clients.test.ts b/test/clients.test.ts index 0e1a801c3..3aebcc421 100644 --- a/test/clients.test.ts +++ b/test/clients.test.ts @@ -270,6 +270,45 @@ describe('coordinator behavioral-contract parity', () => { }); }); +/** + * Host feature matrix (test-fixtures/spec/suite-v0.2/host-feature-matrix.json): the projected digest is the only + * coordinator text non-Copilot hosts load by default. These assertions pin what the live runs on Claude Code and + * OpenCode proved the digest carries, and record (as one `it.fails` per host and gap) the canonical sections it + * still lacks. When the stack adds one of those sections for a host, that host's `it.fails` turns red: drop + * `.fails` for it and flip the matrix cell's capability from `unsupported` to `supported`. The matrix's `expectedFailures[].test` + * is the title below without the ` []` suffix; `test/squad-20-host-feature-matrix.test.ts` checks both. + */ +describe('coordinator digest vs. host feature matrix', () => { + const sections: Array<[string, RegExp[]]> = [ + ['Dispatch adapter per host', [/## Dispatch adapter: /, /## Transport/]], + ['Host-prefixed tool names (Claude, OpenCode, Kiro)', [/mcp__squad_state__squad_state_read/, /squad_state_squad_state_read/, /@squad_state\/squad_state_read/]], + ['Worktree + issue-lifecycle references', [/worktree-reference\.md/, /issue-lifecycle\.md/]], + ['Canonical file is authoritative when present', [/\.github\/agents\/squad\.agent\.md/, /authoritative coordinator contract/]], + ]; + for (const id of CLIENT_IDS) { + it(`${id} digest carries the host-specific sections the live runs relied on`, () => { + const text = buildCoordinatorInstructions(id); + for (const [name, pats] of sections) for (const p of pats) expect(text, `${id}: ${name} ${p}`).toMatch(p); + }); + } + + const gaps: Array<[string, RegExp, string]> = [ + ['team-root resolution (teamRoot / stateLocation / TEAM_ROOT)', /teamRoot|stateLocation|TEAM_ROOT/, 'monorepo-team-root, dual-root-remote-mode'], + ['upstream inheritance (upstream.json)', /upstream\.json/, 'upstream-inheritance (F1)'], + ['Azure DevOps issue tracking (az boards / ADO)', /az boards|Azure DevOps/, 'azure-devops (F3)'], + ['GitLab issue tracking (glab)', /glab|GitLab/, 'gitlab-issues (F2)'], + ['per-agent model / reasoning / context-tier selection', /reasoning[- ]effort|context[- ]tier|defaultModel/, 'model-selection'], + ['plugin marketplace browse on cast', /marketplace/, 'marketplace-plugins'], + ]; + for (const [name, pat, cells] of gaps) { + for (const id of CLIENT_IDS) { + it.fails(`digest gap (expected until the stack adds it): ${name} [${id}]`, () => { + expect(buildCoordinatorInstructions(id), `${id}: ${name} (matrix cells: ${cells})`).toMatch(pat); + }); + } + } +}); + describe('copilot adapter', () => { it('projects only .mcp.json with squad_state', () => { installClients(['copilot'], ctx()); diff --git a/test/squad-20-host-feature-matrix.test.ts b/test/squad-20-host-feature-matrix.test.ts new file mode 100644 index 000000000..aeded499b --- /dev/null +++ b/test/squad-20-host-feature-matrix.test.ts @@ -0,0 +1,491 @@ +/** + * Host feature matrix: `test-fixtures/spec/suite-v0.2/host-feature-matrix.json` is the source of truth for + * which Squad feature works on which host and how each cell was validated. + * + * Always-on layers + * 1. Schema + evidence integrity: every `validated-test:::` reference must point at an existing + * test (file present, name present), every `validated-manual:lab:` must have a recorded live run + * for that host, the rendered docs page must match the JSON, and host runtime flags must agree with + * `CAPABILITY_TOKENS_BY_HOST`. + * 2. Bridge scenarios (no CLI, no model): the `state-mcp` session resolves the right `.squad/` from a monorepo + * subfolder and a remote-mode satellite, and routes `squad_decide` into the orphan / two-layer backends. + * + * Opt-in layers + * 3. SQUAD_REAL_CLI_TESTS=1: real host binaries read the projections from a monorepo subfolder (no model). + * 4. SQUAD_REAL_MODEL_TESTS=1 (implies 3): one headless coordinator turn per installed host against a real + * model, asserting the roster is read through the host-prefixed `squad_state` tool. + */ +import { afterAll, beforeAll, describe, expect, it } from 'vitest'; +import { execFileSync, spawnSync } from 'node:child_process'; +import fs from 'node:fs'; +import os from 'node:os'; +import path from 'node:path'; +import { pathToFileURL } from 'node:url'; +import { CAPABILITY_TOKENS_BY_HOST, CLIENT_IDS, extractCanonicalCoordinatorHeadings } from '../packages/squad-sdk/src/client/adapters/index.js'; +import { installClients } from '../packages/squad-sdk/src/client/index.js'; +import { createStateMcpSession } from '../packages/squad-cli/src/cli/commands/state-mcp.js'; +import { migrateStateBackend } from '../packages/squad-cli/src/cli/commands/migrate-backend.js'; +import { clearResolveSquadCache } from '../packages/squad-sdk/src/resolution.js'; + +const ROOT = path.resolve(__dirname, '..'); +const MATRIX_PATH = path.join(ROOT, 'test-fixtures', 'spec', 'suite-v0.2', 'host-feature-matrix.json'); +const PAGE_PATH = path.join(ROOT, 'docs', 'src', 'content', 'docs', 'reference', 'host-feature-matrix.md'); +const RENDERER = pathToFileURL(path.join(ROOT, 'scripts', 'render-host-feature-matrix.mjs')).href; + +type Capability = 'supported' | 'degraded' | 'unsupported' | 'n/a'; +type Validation = 'validated-live' | 'validated-test' | 'static-only' | 'untested' | 'blocked'; +interface Cell { capability: Capability; validation: Validation; blockedReason?: string; expectedFailure?: boolean; mechanism: string; evidence: string[]; notes?: string } +interface Feature { id: string; name: string; area: string; dependsOn: string[]; hostIndependent?: boolean; cells: Record } +interface LiveRun { host: string; scenario: string; date: string; outcome: 'pass' | 'partial' | 'fail' | 'blocked'; observedTools?: string[]; notes?: string } +interface ExpectedFailure { featureId: string; test: string; kind: string; perHost?: boolean; hosts?: string[]; meaning: string } +interface Matrix { + protocol: string; + hosts: Record; + features: Feature[]; + liveRuns: LiveRun[]; + expectedFailures: ExpectedFailure[]; + limitations?: string[]; + capabilities: Record; + validationLevels: Record; + evidenceKinds: Record; +} + +const matrix = JSON.parse(fs.readFileSync(MATRIX_PATH, 'utf8')) as Matrix; +const HOSTS = Object.keys(matrix.hosts); +const CAPABILITIES: Capability[] = ['supported', 'degraded', 'unsupported', 'n/a']; +const VALIDATION_LEVELS: Validation[] = ['validated-live', 'validated-test', 'static-only', 'untested', 'blocked']; +const EVIDENCE_RE = /^(validated-test:[^:]+::.+|validated-manual:lab:[a-z0-9-]+@\d{4}-\d{2}-\d{2}|static-only)$/; +/** Hosts with a passing live run on the reference machine; only these may carry `validated-live`. */ +const LIVE_HOSTS = new Set(['claude', 'opencode']); + +const ROSTER = '| Name | Role | Charter | Status |\n|---|---|---|---|\n| Noether | Lead Architect | `.squad/agents/noether/charter.md` | βœ… Active |\n| Galois | Backend Engineer | `.squad/agents/galois/charter.md` | βœ… Active |\n'; +const THIS_FILE = 'test/squad-20-host-feature-matrix.test.ts'; + +// ─── 1. schema + evidence integrity ───────────────────────────────────────── + +describe('host-feature-matrix.json integrity', () => { + it('covers every SDK client id with a complete cell per feature', () => { + expect([...HOSTS].sort()).toEqual([...CLIENT_IDS].sort()); + expect(matrix.features.length).toBeGreaterThanOrEqual(40); + const ids = new Set(); + for (const f of matrix.features) { + expect(ids.has(f.id), `duplicate feature id ${f.id}`).toBe(false); + ids.add(f.id); + expect(f.dependsOn.length, `${f.id}: dependsOn`).toBeGreaterThan(0); + for (const d of f.dependsOn) expect(['a', 'b', 'c', 'd', 'e'], `${f.id}: class ${d}`).toContain(d); + for (const h of HOSTS) { + const c = f.cells[h]; + expect(c, `${f.id}: missing cell for ${h}`).toBeDefined(); + expect(CAPABILITIES, `${f.id}/${h}: capability ${c!.capability}`).toContain(c!.capability); + expect(VALIDATION_LEVELS, `${f.id}/${h}: validation ${c!.validation}`).toContain(c!.validation); + expect(c!.mechanism.length, `${f.id}/${h}: mechanism`).toBeGreaterThan(10); + expect(Array.isArray(c!.evidence), `${f.id}/${h}: evidence array`).toBe(true); + for (const v of c!.evidence) expect(v, `${f.id}/${h}: evidence entry ${v}`).toMatch(EVIDENCE_RE); + // The validation level must be backed by evidence of that kind β€” the two axes stay honest. + const kinds = new Set(c!.evidence.map((v) => v.split(':')[0])); + if (c!.validation === 'validated-live') { + expect(LIVE_HOSTS.has(h), `${f.id}/${h}: validated-live is only possible for hosts with a passing live run (Claude Code, OpenCode)`).toBe(true); + expect(kinds.has('validated-manual'), `${f.id}/${h}: validated-live needs a validated-manual:lab entry`).toBe(true); + } + if (c!.validation === 'validated-test') expect(kinds.has('validated-test'), `${f.id}/${h}: validated-test needs a validated-test entry`).toBe(true); + if (c!.validation === 'static-only' || c!.validation === 'untested' || c!.validation === 'blocked') { + expect(kinds.has('validated-test') || kinds.has('validated-manual'), `${f.id}/${h}: ${c!.validation} cell must not list test/live evidence`).toBe(false); + } + if (c!.validation === 'blocked') expect(c!.blockedReason, `${f.id}/${h}: blocked needs blockedReason`).toBeTruthy(); + else expect(c!.blockedReason, `${f.id}/${h}: blockedReason only with blocked`).toBeUndefined(); + if (c!.capability === 'n/a') expect(c!.validation, `${f.id}/${h}: n/a cells are static-only`).toBe('static-only'); + } + } + for (const k of CAPABILITIES) expect(matrix.capabilities[k], `capability "${k}" is not defined on the page`).toBeTruthy(); + for (const k of VALIDATION_LEVELS) expect(matrix.validationLevels[k], `validation level "${k}" is not defined on the page`).toBeTruthy(); + }); + + it('every validated-test reference names a test that exists', () => { + const cache = new Map(); + const read = (rel: string) => { + if (!cache.has(rel)) { + const abs = path.join(ROOT, rel); + expect(fs.existsSync(abs), `referenced test file missing: ${rel}`).toBe(true); + cache.set(rel, fs.readFileSync(abs, 'utf8')); + } + return cache.get(rel)!; + }; + for (const f of matrix.features) for (const h of HOSTS) for (const v of f.cells[h]!.evidence) { + if (!v.startsWith('validated-test:')) continue; + const [, file, name] = /^validated-test:([^:]+)::(.+)$/.exec(v)!; + const src = read(file!); + if (name !== '*') expect(src.includes(name!), `${f.id}/${h}: "${name}" not found in ${file}`).toBe(true); + } + }); + + it('every validated-manual:lab reference has a recorded live run for that host', () => { + expect(Array.isArray(matrix.liveRuns)).toBe(true); + for (const f of matrix.features) for (const h of HOSTS) for (const v of f.cells[h]!.evidence) { + const m = /^validated-manual:lab:([a-z0-9-]+)(?:@.*)?$/.exec(v); + if (!m) continue; + const run = matrix.liveRuns.find((r) => r.host === h && r.scenario === m[1]); + expect(run, `${f.id}/${h}: no live run recorded for scenario ${m[1]}`).toBeDefined(); + expect(['pass', 'partial'], `${f.id}/${h}: live run ${m[1]} outcome ${run!.outcome} cannot back a validated cell`).toContain(run!.outcome); + } + }); + + it('expected-failure cells are unsupported with a note, and no failed or blocked live run raises a cell to validated-live', () => { + for (const f of matrix.features) for (const h of HOSTS) { + const c = f.cells[h]!; + if (c.expectedFailure) { + expect(c.notes, `${f.id}/${h}: expected-failure cell needs a note`).toBeTruthy(); + expect(c.capability, `${f.id}/${h}: a digest gap is unsupported for that host, not degraded or supported`).toBe('unsupported'); + } + } + for (const r of matrix.liveRuns.filter((r) => r.outcome === 'fail' || r.outcome === 'blocked')) { + for (const f of matrix.features) { + const c = f.cells[r.host]!; + if (c.evidence.some((v) => v.includes(`lab:${r.scenario}`))) expect(c.validation, `${f.id}/${r.host}: ${r.outcome} run ${r.scenario} cannot make the cell validated-live`).not.toBe('validated-live'); + } + } + }); + + it('every expected failure resolves to one it.fails title per listed host, and every failing cell is an expected failure', () => { + expect(Array.isArray(matrix.expectedFailures)).toBe(true); + expect(matrix.expectedFailures.length).toBeGreaterThan(0); + const cache = new Map(); + const read = (rel: string) => { + if (!cache.has(rel)) cache.set(rel, fs.readFileSync(path.join(ROOT, rel), 'utf8').replace(/\r\n/g, '\n')); + return cache.get(rel)!; + }; + const covered = new Set(); + for (const e of matrix.expectedFailures) { + const feat = matrix.features.find((f) => f.id === e.featureId); + expect(feat, `expected failure for unknown feature ${e.featureId}`).toBeDefined(); + expect(e.kind).toBe('it.fails'); + const [, file, title] = /^([^:]+)::(.+)$/.exec(e.test)!; + const src = read(file!); + const hosts = e.perHost ? e.hosts ?? [] : ['']; + expect(hosts.length, `${e.featureId}: perHost expected failure lists no hosts`).toBeGreaterThan(0); + // Per-host titles are generated as `${PREFIX}${name} [${id}]` for every id in CLIENT_IDS; the matrix stores + // the title without the host suffix. Resolve it against the gap name literal and the generating template. + const PREFIX = 'digest gap (expected until the stack adds it): '; + if (e.perHost) { + expect(title!.startsWith(PREFIX), `${e.featureId}: per-host expected failure title must start with "${PREFIX}"`).toBe(true); + const gapName = title!.slice(PREFIX.length); + expect(src.includes(`['${gapName}', `), `${e.featureId}: gap "${gapName}" is not registered in ${file}`).toBe(true); + expect(src.includes(`it.fails(\`${PREFIX}\${name} [\${id}]\``), `${file}: per-host it.fails template changed; update the matrix`).toBe(true); + expect(src.includes('for (const id of CLIENT_IDS) {\n it.fails('), `${file}: per-host it.fails must iterate CLIENT_IDS`).toBe(true); + for (const h of hosts) expect(CLIENT_IDS, `${e.featureId}: host ${h} is not a client id`).toContain(h); + } else { + expect(src.includes(title!), `${e.featureId}: it.fails title "${title}" not found in ${file}`).toBe(true); + } + for (const h of hosts) { + if (e.perHost) { + const c = feat!.cells[h]; + expect(c, `${e.featureId}/${h}: no cell for a listed host`).toBeDefined(); + expect(c!.expectedFailure, `${e.featureId}/${h}: expected-failure cell must be flagged expectedFailure`).toBe(true); + expect(c!.capability, `${e.featureId}/${h}: expected-failure cell is unsupported`).toBe('unsupported'); + expect(c!.evidence.some((v) => v.startsWith(`validated-test:${file}::`)), `${e.featureId}/${h}: evidence must cite the gap test in ${file}`).toBe(true); + covered.add(`${e.featureId}/${h}`); + } + } + } + for (const f of matrix.features) for (const h of HOSTS) { + if (f.cells[h]!.expectedFailure) expect(covered.has(`${f.id}/${h}`), `${f.id}/${h} is flagged expectedFailure but has no expectedFailures entry`).toBe(true); + } + }); + + it('every canonicalSections entry is a real heading in .github/agents/squad.agent.md', () => { + const canonical = fs.readFileSync(path.join(ROOT, '.github', 'agents', 'squad.agent.md'), 'utf8'); + const headings = new Set(extractCanonicalCoordinatorHeadings(canonical)); + for (const f of matrix.features as Array) { + for (const s of f.canonicalSections ?? []) expect(headings.has(s), `${f.id}: canonical section "${s}" is not a ##/### heading`).toBe(true); + } + }); + + it('host runtime flags agree with CAPABILITY_TOKENS_BY_HOST', () => { + for (const h of CLIENT_IDS) { + const tokens = CAPABILITY_TOKENS_BY_HOST[h]; + expect(matrix.hosts[h]!.runtime.subagents, `${h}: subagents`).toBe(tokens.includes('subagents')); + expect(matrix.hosts[h]!.runtime.backgroundRuns, `${h}: background-runs`).toBe(tokens.includes('background-runs')); + } + }); + + it('hosts without the background-runs token are never "supported" for background-agents', () => { + const f = matrix.features.find((x) => x.id === 'background-agents')!; + for (const h of CLIENT_IDS) if (!CAPABILITY_TOKENS_BY_HOST[h].includes('background-runs')) expect(f.cells[h]!.capability, h).not.toBe('supported'); + }); + + it('the rendered reference page is up to date with the JSON', async () => { + const { render } = (await import(RENDERER)) as { render: (m: unknown) => string }; + const expected = render(matrix).replace(/\r\n/g, '\n'); + const actual = fs.readFileSync(PAGE_PATH, 'utf8').replace(/\r\n/g, '\n'); + expect(actual, 'docs/src/content/docs/reference/host-feature-matrix.md is stale; run node scripts/render-host-feature-matrix.mjs').toBe(expected); + }); +}); + +// ─── 2. bridge scenarios (deterministic; no CLI, no model) ────────────────── + +type Rpc = { jsonrpc: '2.0'; id: string | number | null; result?: any; error?: { code: number; message: string } }; + +async function bridge(startDir: string) { + const out: Rpc[] = []; + const session = createStateMcpSession(startDir, (m) => out.push(m as Rpc)); + let id = 0; + const call = async (name: string, args: Record = {}) => { + const myId = ++id; + await session.handleRequest({ jsonrpc: '2.0', id: myId, method: 'tools/call', params: { name, arguments: args } }); + const msg = out.find((m) => m.id === myId)!; + expect(msg.error, `${name}: ${JSON.stringify(msg.error)}`).toBeUndefined(); + const text: string = msg.result?.content?.[0]?.text ?? ''; + return { text, isError: msg.result?.isError === true }; + }; + return { call }; +} + +function gitInit(dir: string) { + fs.mkdirSync(dir, { recursive: true }); + const git = (args: string[]) => execFileSync('git', args, { cwd: dir, encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }); + git(['init', '-q', '-b', 'main']); + git(['config', 'user.email', 'lab@example.com']); + git(['config', 'user.name', 'Lab']); + fs.writeFileSync(path.join(dir, 'README.md'), '# lab\n'); + git(['add', 'README.md']); + git(['commit', '-q', '-m', 'init']); + return git; +} + +function squadDir(dir: string, config: Record = {}) { + fs.mkdirSync(path.join(dir, '.squad', 'decisions', 'inbox'), { recursive: true }); + fs.writeFileSync(path.join(dir, '.squad', 'config.json'), JSON.stringify({ version: 1, ...config }, null, 2) + '\n'); + fs.writeFileSync(path.join(dir, '.squad', 'team.md'), `# Squad Team\n\n> ${path.basename(dir)}\n\n## Members\n\n${ROSTER}`); + fs.writeFileSync(path.join(dir, '.squad', 'decisions.md'), '# Decisions\n'); +} + +describe('bridge scenarios: state-mcp resolution the host coordinator relies on', () => { + let tmp: string; + beforeAll(() => { tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'squad-hfm-')); }); + afterAll(() => { + clearResolveSquadCache(); + fs.rmSync(tmp, { recursive: true, force: true, maxRetries: 5, retryDelay: 200 }); + }); + + it('state-mcp resolves the root .squad when launched from a monorepo subfolder', async () => { + const repo = path.join(tmp, 'mono'); + gitInit(repo); + squadDir(repo); + const sub = path.join(repo, 'packages', 'api'); + fs.mkdirSync(sub, { recursive: true }); + clearResolveSquadCache(); + const b = await bridge(sub); + const team = await b.call('squad_state_read', { key: 'team.md' }); + expect(team.text, 'roster from the repo-root .squad must be visible from packages/api').toContain('Noether'); + const decided = await b.call('squad_decide', { author: 'Noether', summary: 'Mono decision', body: 'from a subfolder' }); + expect(decided.isError).toBe(false); + const inbox = fs.readdirSync(path.join(repo, '.squad', 'decisions', 'inbox')); + expect(inbox.some((f) => /mono-decision/.test(f)), `inbox at the repo root got the decision: ${inbox.join(',')}`).toBe(true); + expect(fs.existsSync(path.join(sub, '.squad')), 'no stray .squad created under the subfolder').toBe(false); + }, 60_000); + + it('state-mcp follows config.json teamRoot from a satellite repo (remote mode)', async () => { + const base = path.join(tmp, 'base'); + gitInit(base); + squadDir(base); + const sat = path.join(tmp, 'satellite'); + gitInit(sat); + fs.mkdirSync(path.join(sat, '.squad'), { recursive: true }); + fs.writeFileSync(path.join(sat, '.squad', 'config.json'), JSON.stringify({ version: 1, teamRoot: '../base', projectKey: null }, null, 2) + '\n'); + clearResolveSquadCache(); + const b = await bridge(sat); + const team = await b.call('squad_state_read', { key: 'team.md' }); + expect(team.text, 'satellite reads the team root roster, so the host coordinator must not see Init Mode').toContain('Noether'); + const decided = await b.call('squad_decide', { author: 'Galois', summary: 'Satellite decision', body: 'recorded from the satellite' }); + expect(decided.isError).toBe(false); + const inbox = fs.readdirSync(path.join(base, '.squad', 'decisions', 'inbox')); + expect(inbox.some((f) => /satellite-decision/.test(f)), `decision must land in the team root inbox: ${inbox.join(',')}`).toBe(true); + expect(fs.existsSync(path.join(sat, '.squad', 'decisions')), 'satellite keeps no local decisions').toBe(false); + }, 60_000); + + it.each(['orphan', 'two-layer'] as const)('squad_decide over the bridge lands in the squad-state branch for the %s backend, not the working tree', async (backend) => { + const repo = path.join(tmp, backend); + const git = gitInit(repo); + squadDir(repo); + git(['add', '-A']); + git(['commit', '-q', '-m', 'squad']); + await migrateStateBackend(repo, backend); + clearResolveSquadCache(); + const b = await bridge(repo); + const health = await b.call('squad_state_health'); + expect(health.isError).toBe(false); + const decided = await b.call('squad_decide', { author: 'Noether', summary: `${backend} decision`, body: 'port 7777' }); + expect(decided.isError, decided.text).toBe(false); + const listed = await b.call('squad_state_list', { dir: 'decisions/inbox' }); + expect(listed.text, `${backend}: inbox listing`).toMatch(new RegExp(`${backend}-decision`)); + const branchFiles = git(['ls-tree', '-r', '--name-only', 'squad-state']); + expect(branchFiles, `${backend}: decision committed to squad-state`).toMatch(new RegExp(`decisions/inbox/.*${backend}-decision`)); + const wtInbox = fs.existsSync(path.join(repo, '.squad', 'decisions', 'inbox')) ? fs.readdirSync(path.join(repo, '.squad', 'decisions', 'inbox')) : []; + expect(wtInbox.filter((f) => f.includes(`${backend}-decision`)), `${backend}: working tree must not receive the decision`).toEqual([]); + }, 180_000); + + // Finding F6: the digest promises `squad_state_health` "reports the backend: local, orphan, two-layer", but the tool + // returns the storage class name. This stays `it.fails` until the SDK tool reports `backend.name`; flipping it green + // then is the signal to drop `.fails` and update the matrix cell. + it.fails('squad_state_health names the configured backend (orphan) as the coordinator digest promises', async () => { + const repo = path.join(tmp, 'health-orphan'); + const git = gitInit(repo); + squadDir(repo); + git(['add', '-A']); + git(['commit', '-q', '-m', 'squad']); + await migrateStateBackend(repo, 'orphan'); + clearResolveSquadCache(); + const b = await bridge(repo); + const health = await b.call('squad_state_health'); + expect(health.text, 'health text should name the backend, got the storage class instead').toMatch(/\borphan\b/); + }, 180_000); +}); + +// ─── 3./4. real host binaries (opt-in) ────────────────────────────────────── + +const REAL_CLI = process.env['SQUAD_REAL_CLI_TESTS'] === '1' || process.env['SQUAD_REAL_MODEL_TESTS'] === '1'; +const REAL_MODEL = process.env['SQUAD_REAL_MODEL_TESTS'] === '1'; + +function which(cmd: string): string | undefined { + const exts = process.platform === 'win32' ? (process.env['PATHEXT'] ?? '.EXE;.CMD;.BAT').split(';') : ['']; + for (const dir of (process.env['PATH'] ?? '').split(path.delimiter).filter(Boolean)) { + for (const ext of exts) { + const candidate = path.join(dir, cmd + ext.toLowerCase()); + try { if (fs.statSync(candidate).isFile()) return candidate; } catch { /* not here */ } + } + } + return undefined; +} +function run(bin: string, args: string[], cwd: string, timeout = 180_000) { + const viaCmd = process.platform === 'win32' && /\.(cmd|bat|ps1)$/i.test(bin); + const file = viaCmd ? (process.env['ComSpec'] ?? 'cmd.exe') : bin; + const argv = viaCmd ? ['/d', '/s', '/c', `""${bin}" ${args.map((a) => `"${a.replace(/"/g, "'")}"`).join(' ')}"`] : args; + return spawnSync(file, argv, { cwd, encoding: 'utf8', timeout, windowsVerbatimArguments: viaCmd, env: { ...process.env, SQUAD_NO_PERSONAL: '1' } }); +} +const CLAUDE = REAL_CLI ? which('claude') : undefined; +const OPENCODE = REAL_CLI ? which('opencode') : undefined; +const MCP_STDIO_STUB = + 'process.stdin.on("data",d=>{for(const l of String(d).split(/\\r?\\n/).filter(Boolean)){try{const j=JSON.parse(l);if(j.id!==undefined)process.stdout.write(JSON.stringify({jsonrpc:"2.0",id:j.id,result:{protocolVersion:"2024-11-05",capabilities:{tools:{}},serverInfo:{name:"squad_state",version:"1.0.0"},tools:[]}})+"\\n")}catch{}}})'; + +describe.skipIf(!REAL_CLI)('real host binaries read root projections from a monorepo subfolder (SQUAD_REAL_CLI_TESTS=1)', () => { + let repo: string; + let sub: string; + beforeAll(() => { + repo = fs.mkdtempSync(path.join(os.tmpdir(), 'squad-hfm-cli-')); + gitInit(repo); + squadDir(repo); + sub = path.join(repo, 'packages', 'api'); + fs.mkdirSync(sub, { recursive: true }); + const results = installClients(['claude', 'opencode'], { root: repo, mcp: { command: 'node', args: ['-e', MCP_STDIO_STUB] } }); + expect(results.filter((r) => r.action === 'error')).toEqual([]); + }); + afterAll(() => { + for (const f of [path.join(sub, 'NUL'), path.join(repo, 'NUL')]) if (fs.existsSync(f)) spawnSync(process.env['ComSpec'] ?? 'cmd.exe', ['/c', `del "\\\\?\\${f}"`]); + fs.rmSync(repo, { recursive: true, force: true, maxRetries: 10, retryDelay: 300 }); + }); + + it.skipIf(!CLAUDE)('claude lists the root .mcp.json squad_state server from packages/api (approval is a separate, per-project step)', () => { + const r = run(CLAUDE!, ['mcp', 'list'], sub); + expect(`${r.stdout}${r.stderr}`, 'claude mcp list from a subfolder should still see the repo-root squad_state server').toMatch(/squad_state/); + }, 120_000); + + it.skipIf(!OPENCODE)('opencode resolves the squad primary agent and the squad_state MCP entry from packages/api', () => { + const r = run(OPENCODE!, ['debug', 'config'], sub); + const cfg = JSON.parse(r.stdout); + expect(cfg.agent?.squad?.mode, 'opencode agent.squad.mode from a subfolder').toBe('primary'); + expect(cfg.mcp?.squad_state?.type, 'opencode mcp.squad_state from a subfolder').toBe('local'); + }, 120_000); +}); + +/** + * Tee for the real `squad state-mcp` bridge: forwards stdio untouched and appends every JSON-RPC line in both + * directions to the transcript file given as its first argument. The live-model tests assert on the transcript + * (a successful `tools/call` of the roster tool with `key: "team.md"`), not on what the model printed. + */ +const MCP_TEE = ` + const { spawn } = require('node:child_process'); + const fs = require('node:fs'); + const log = process.argv[2]; + const child = spawn(process.execPath, process.argv.slice(3), { stdio: ['pipe', 'pipe', 'inherit'] }); + const tee = (dir) => (chunk) => { if (log) fs.appendFileSync(log, String(chunk).split(/\\r?\\n/).filter(Boolean).map((l) => dir + ' ' + l).join('\\n') + '\\n'); }; + process.stdin.on('data', (c) => { tee('>')(c); child.stdin.write(c); }); + process.stdin.on('end', () => child.stdin.end()); + child.stdout.on('data', (c) => { tee('<')(c); process.stdout.write(c); }); + child.on('exit', (code) => process.exit(code ?? 0)); +`; + +/** Parse a tee transcript and return the ids of successful roster reads (`squad_state_read` with key team.md). */ +function successfulRosterReads(transcript: string): number[] { + const requests = new Map(); + const ok: number[] = []; + for (const line of transcript.split(/\r?\n/)) { + const m = /^([<>]) (\{.*\})$/.exec(line); + if (!m) continue; + let msg: { id?: string | number; method?: string; params?: { name?: string; arguments?: { key?: string } }; result?: { isError?: boolean }; error?: unknown }; + try { msg = JSON.parse(m[2]!); } catch { continue; } + if (m[1] === '>' && msg.method === 'tools/call' && msg.id !== undefined && msg.params?.name) { + requests.set(msg.id, { name: msg.params.name, key: msg.params.arguments?.key }); + } else if (m[1] === '<' && msg.id !== undefined && requests.has(msg.id) && !msg.error && !msg.result?.isError) { + const req = requests.get(msg.id)!; + if (/squad_state_read$/.test(req.name) && req.key === 'team.md') ok.push(Number(msg.id)); + } + } + return ok; +} + +describe('tee transcript parser (host-independent)', () => { + it('counts only successful squad_state_read calls for team.md', () => { + const t = [ + '> {"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"mcp__squad_state__squad_state_read","arguments":{"key":"team.md"}}}', + '< {"jsonrpc":"2.0","id":1,"result":{"content":[{"type":"text","text":"roster"}]}}', + '> {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"squad_state_read","arguments":{"key":"routing.md"}}}', + '< {"jsonrpc":"2.0","id":2,"result":{"content":[]}}', + '> {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"squad_state_read","arguments":{"key":"team.md"}}}', + '< {"jsonrpc":"2.0","id":3,"result":{"isError":true,"content":[]}}', + '> {"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"squad_state_read","arguments":{"key":"team.md"}}}', + '< {"jsonrpc":"2.0","id":4,"error":{"code":-1,"message":"nope"}}', + ].join('\n'); + expect(successfulRosterReads(t)).toEqual([1]); + expect(successfulRosterReads('Noether mcp__squad_state__squad_state_read team.md')).toEqual([]); + }); +}); + +describe.skipIf(!REAL_MODEL)('headless coordinator turn against a real model (SQUAD_REAL_MODEL_TESTS=1)', () => { + let repo: string; + let teeLog: string; + const PROMPT = 'Who is on the team? Answer in one line (Direct mode) and name the exact squad_state tool you used to read the roster.'; + beforeAll(() => { + repo = fs.mkdtempSync(path.join(os.tmpdir(), 'squad-hfm-model-')); + gitInit(repo); + squadDir(repo); + // real bridge: the CLI source through the repo's tsx-free loader is overkill here; use the built CLI when present + const cli = path.join(ROOT, 'packages', 'squad-cli', 'dist', 'cli-entry.js'); + expect(fs.existsSync(cli), 'SQUAD_REAL_MODEL_TESTS needs a built CLI (npm run build) for the squad_state bridge').toBe(true); + teeLog = path.join(repo, 'mcp-transcript.log'); + const teeScript = path.join(repo, 'mcp-tee.cjs'); + fs.writeFileSync(teeScript, MCP_TEE); + const results = installClients(['claude', 'opencode'], { root: repo, mcp: { command: process.execPath, args: [teeScript, teeLog, cli, 'state-mcp'] } }); + expect(results.filter((r) => r.action === 'error')).toEqual([]); + }); + afterAll(() => { + if (fs.existsSync(path.join(repo, 'NUL'))) spawnSync(process.env['ComSpec'] ?? 'cmd.exe', ['/c', `del "\\\\?\\${path.join(repo, 'NUL')}"`]); + fs.rmSync(repo, { recursive: true, force: true, maxRetries: 10, retryDelay: 300 }); + }); + + it.skipIf(!CLAUDE)('claude --agent squad reads the roster through mcp__squad_state__squad_state_read (needs --mcp-config headlessly)', () => { + const r = run(CLAUDE!, ['-p', PROMPT, '--agent', 'squad', '--mcp-config', path.join(repo, '.mcp.json'), '--output-format', 'json', '--permission-mode', 'bypassPermissions', '--max-turns', '8'], repo, 300_000); + const text = r.stdout; + expect(text, `claude run failed: ${r.stderr.slice(-500)}`).toMatch(/Noether/); + const transcript = fs.existsSync(teeLog) ? fs.readFileSync(teeLog, 'utf8') : ''; + expect(successfulRosterReads(transcript).length, `claude: no successful squad_state_read(team.md) over the bridge; transcript:\n${transcript.slice(-2000)}`).toBeGreaterThan(0); + }, 320_000); + + it.skipIf(!OPENCODE)('opencode --agent squad reads the roster through squad_state_squad_state_read', () => { + const r = run(OPENCODE!, ['run', '--agent', 'squad', '--format', 'json', '--auto', PROMPT], repo, 300_000); + expect(r.stdout, `opencode run failed: ${r.stderr.slice(-500)}`).toMatch(/Noether/); + const transcript = fs.existsSync(teeLog) ? fs.readFileSync(teeLog, 'utf8') : ''; + expect(successfulRosterReads(transcript).length, `opencode: no successful squad_state_read(team.md) over the bridge; transcript:\n${transcript.slice(-2000)}`).toBeGreaterThan(0); + }, 320_000); +}); + +// Referenced by the matrix for host-independent bridge evidence; keep the file name stable. +export const HOST_FEATURE_MATRIX_TEST = THIS_FILE;