GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing github.com — feat(claude): Claude projection v2: member subagents, skills, governance hooks, watch preset by bradygaster · Pull Request #2450 · github/squad Conversation
Collaborator
WhatClaude projection v2 for Claude Code (#2442, part of epic #2438), shipped as one projection-version bump:
WhyCloses #2442. Claude Code had only the coordinator file, so it couldn't dispatch members as real subagents, carried the full coordinator text in every session, had no governance hooks and couldn't run How
Note on history: e33840c accidentally included
|
🟠 Impact Analysis — PR #2450Risk tier: 🟠 HIGH 📊 Summary
🎯 Risk Factors
📦 Modules Affecteddocs (4 files)
root (6 files)
squad-cli (16 files)
squad-sdk (10 files)
tests (10 files)
|
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
🏗️ Architectural Review
Automated architectural review — informational only. |
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 15 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with dev |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | No .squad/ or docs/proposals/ files |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | 2 active Copilot thread(s) resolved (9 outdated skipped) |
| ❌ | CI passing | 1 check(s) still running |
| File | +/− |
|---|---|
.changeset/claude-governance-hooks.md |
+6 −0 |
.changeset/claude-member-subagents.md |
+6 −0 |
.changeset/claude-projection-v2.md |
+5 −0 |
.changeset/claude-skills-projection.md |
+5 −0 |
.changeset/claude-watch-preset.md |
+5 −0 |
docs/specification/client-harness-adapters-v0.2.md |
+96 −5 |
docs/src/content/docs/features/ralph.md |
+40 −1 |
docs/src/content/docs/reference/host-feature-matrix.md |
+13 −13 |
docs/src/content/docs/scenarios/client-compatibility.md |
+30 −4 |
packages/squad-cli/src/cli-entry.ts |
+27 −1 |
packages/squad-cli/src/cli/commands/cast.ts |
+19 −0 |
packages/squad-cli/src/cli/commands/hook.ts |
+54 −0 |
packages/squad-cli/src/cli/commands/lockout.ts |
+95 −0 |
packages/squad-cli/src/cli/commands/watch/agent-spawn.ts |
+85 −5 |
packages/squad-cli/src/cli/commands/watch/capabilities/decision-hygiene.ts |
+2 −2 |
packages/squad-cli/src/cli/commands/watch/capabilities/execute.ts |
+28 −11 |
packages/squad-cli/src/cli/commands/watch/capabilities/monitor-email.ts |
+4 −3 |
packages/squad-cli/src/cli/commands/watch/capabilities/monitor-teams.ts |
+4 −3 |
packages/squad-cli/src/cli/commands/watch/capabilities/retro.ts |
+2 −2 |
packages/squad-cli/src/cli/commands/watch/claude-mcp.ts |
+27 −0 |
packages/squad-cli/src/cli/commands/watch/config.ts |
+60 −1 |
packages/squad-cli/src/cli/commands/watch/index.ts |
+10 −2 |
packages/squad-cli/src/cli/commands/watch/types.ts |
+9 −0 |
packages/squad-cli/src/cli/core/clients.ts |
+1 −0 |
packages/squad-cli/src/cli/core/command-help.ts |
+2 −0 |
packages/squad-sdk/src/client/adapters/adapters.ts |
+19 −1 |
packages/squad-sdk/src/client/adapters/apply.ts |
+57 −10 |
packages/squad-sdk/src/client/adapters/claude-hooks.ts |
+414 −0 |
packages/squad-sdk/src/client/adapters/claude-members.ts |
+238 −0 |
packages/squad-sdk/src/client/adapters/claude-skills.ts |
+87 −0 |
packages/squad-sdk/src/client/adapters/coordinator.ts |
+95 −2 |
packages/squad-sdk/src/client/adapters/index.ts |
+2 −0 |
packages/squad-sdk/src/client/adapters/lockout.ts |
+329 −0 |
packages/squad-sdk/src/client/adapters/safe-path.ts |
+52 −0 |
packages/squad-sdk/src/client/adapters/types.ts |
+23 −5 |
test-fixtures/spec/suite-v0.2/host-feature-matrix.json |
+24 −19 |
test/claude-hooks.test.ts |
+332 −0 |
test/claude-members.test.ts |
+232 −0 |
test/claude-projection-v2-rollback.test.ts |
+145 −0 |
test/claude-skills.test.ts |
+111 −0 |
test/claude-v2-review-fixes.test.ts |
+241 −0 |
test/cli/watch-claude-preset.test.ts |
+236 −0 |
test/clients.test.ts |
+35 −9 |
test/speed-gates.test.ts |
+2 −2 |
test/squad-20-all-scenarios.e2e.test.ts |
+12 −3 |
test/squad-20-host-feature-matrix.test.ts |
+1 −1 |
Total: +3322 −105
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
Sorry, something went wrong.
There was an error while loading. Please reload this page.
| } | ||
|
|
||
| /** The hook launch command: the MCP launcher with its trailing `state-mcp` replaced. */ | ||
| export function claudeHookLaunch(mcp: McpLaunchSpec, event: ClaudeHookEvent): McpLaunchSpec | null { |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Not changed; leaving this open for a human reviewer. mcp here isn't read from repository content. The running CLI resolves it from its own install (resolveSquadStateMcpSpec): a standalone launcher, node <absolute path>/cli-entry.js, or npx with the exact @bradygaster/squad-cli version. The hook command is that same launcher with state-mcp swapped for hook claude <Event>, and the identical command is already projected into .mcp.json as the squad_state server Claude Code runs, so hooks add no new executable. The suggested allowlist (only squad or a pinned npx package) would also turn hooks off for the common node …/cli-entry.js and standalone installs. I've documented this in a comment on claudeHookLaunch (0653a37).
🤖 Addressed by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…text - docs lint (cspell) rejected "recognises" in harness-adapters §5. - PostToolUse no longer reflects the Agent call's free-text description into the coordinator's context; the handoff envelope keeps only structured fields (review feedback on #2450). - Document why claudeHookLaunch has no command allowlist: the launcher is resolved by the CLI from its own install, never from repo content, and is already projected as the squad_state MCP server. Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Unresolved security flaws allow repository-controlled symlinks to expose private files or modify external governance state, while the Claude MCP configuration bypasses server approval and enables unapproved command execution.
Introduces Claude projection v2 with native member subagents, on-demand skills, advisory governance hooks, and a built-in Claude watch runner. Copilot remains the default runner.
Changes:
This pull request requires changes. Unresolved security and correctness findings block approval, including unsafe source/configuration handling, lockout integrity, and unintended changes to user settings.
| File | Description |
|---|---|
test/squad-20-host-feature-matrix.test.ts |
Updates host-specific capability-gap assertions. |
test/squad-20-all-scenarios.e2e.test.ts |
Includes on-demand skills in coordinator contract checks. |
test/speed-gates.test.ts |
Adjusts the help-length budget for lockout commands. |
test/clients.test.ts |
Extends coordinator, model-selection, and marker-newline coverage. |
test/cli/watch-claude-preset.test.ts |
Covers runner configuration, invocation, and failure detection. |
test/claude-skills.test.ts |
Covers skill projection, precedence, ownership, and cleanup. |
test/claude-projection-v2-rollback.test.ts |
Adds version-stamping, upgrade, and whole-tree rollback checks. |
test/claude-members.test.ts |
Covers charter mapping and member-agent lifecycle. |
test/claude-hooks.test.ts |
Covers hook merging, runtime behavior, and lockout transitions. |
test-fixtures/spec/suite-v0.2/host-feature-matrix.json |
Updates Claude capability statuses and supporting evidence. |
packages/squad-sdk/src/client/adapters/types.ts |
Extends projection ownership, removal, and skipped-result types. |
packages/squad-sdk/src/client/adapters/lockout.ts |
Implements persistent reviewer-lockout state and revision transitions. |
packages/squad-sdk/src/client/adapters/index.ts |
Exports hook and lockout APIs. |
packages/squad-sdk/src/client/adapters/coordinator.ts |
Adds named-member dispatch and extracts on-demand guidance. |
packages/squad-sdk/src/client/adapters/claude-skills.ts |
Projects template and coordinator skills and prunes obsolete files. |
packages/squad-sdk/src/client/adapters/claude-members.ts |
Compiles charters and host settings into member subagents. |
packages/squad-sdk/src/client/adapters/claude-hooks.ts |
Projects advisory hook settings and processes lifecycle events. |
packages/squad-sdk/src/client/adapters/apply.ts |
Adds ownership-aware updates, JSON removal, and newline-preserving blocks. |
packages/squad-sdk/src/client/adapters/adapters.ts |
Assembles and versions the expanded Claude projection. |
packages/squad-cli/src/cli/core/command-help.ts |
Documents Claude watch flags. |
packages/squad-cli/src/cli/core/clients.ts |
Reports skipped user-authored projection files. |
packages/squad-cli/src/cli/commands/watch/types.ts |
Adds runner-preset and Claude flag fields. |
packages/squad-cli/src/cli/commands/watch/index.ts |
Propagates runner settings into watch execution. |
packages/squad-cli/src/cli/commands/watch/config.ts |
Loads and validates runner configuration and permission defaults. |
packages/squad-cli/src/cli/commands/watch/capabilities/monitor-teams.ts |
Adds Claude CLI preflight support for Teams monitoring. |
packages/squad-cli/src/cli/commands/watch/capabilities/monitor-email.ts |
Adds Claude CLI preflight support for email monitoring. |
packages/squad-cli/src/cli/commands/watch/capabilities/execute.ts |
Integrates Claude coordinator execution and result validation. |
packages/squad-cli/src/cli/commands/watch/agent-spawn.ts |
Builds Claude invocations and parses stream-result events. |
packages/squad-cli/src/cli/commands/lockout.ts |
Adds lockout-management and status commands. |
packages/squad-cli/src/cli/commands/hook.ts |
Provides the Claude advisory-hook CLI entry point. |
packages/squad-cli/src/cli/commands/cast.ts |
Refreshes Claude projections after local casting. |
packages/squad-cli/src/cli-entry.ts |
Registers hook/lockout commands and parses runner flags. |
docs/src/content/docs/scenarios/client-compatibility.md |
Documents Claude agents, skills, hooks, and watch usage. |
docs/src/content/docs/reference/host-feature-matrix.md |
Refreshes generated Claude capability documentation. |
docs/src/content/docs/features/ralph.md |
Documents the Claude runner and configuration flags. |
docs/specification/client-harness-adapters-v0.2.md |
Defines projection v2, governance, and ownership contracts. |
.changeset/claude-watch-preset.md |
Announces the Claude watch runner. |
.changeset/claude-skills-projection.md |
Announces native skills and coordinator slimming. |
.changeset/claude-projection-v2.md |
Records projection versioning and marker rollback changes. |
.changeset/claude-member-subagents.md |
Announces charter-based member subagents. |
.changeset/claude-governance-hooks.md |
Announces advisory hooks and lockout commands. |
Review effort: Max (auto)
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
Security:
- watch Claude preset no longer passes the repository's .mcp.json (which
bypassed Claude Code's approval for every server in it); it writes a
private squad_state-only config resolved by the CLI from its own install.
- Charters, routing.md and template SKILL.md files that resolve outside the
team directory through a symlink are no longer copied into .claude/.
- The lockout store refuses a governance/ path that resolves outside the
team directory, and replaces (never writes through) a lockouts.json link.
Correctness:
- squad lockout reads, transitions and writes under an interprocess lock,
so concurrent commands keep every transition.
- `squad lockout status --json` no longer treats --json as the subject.
- Rai and Fact Checker are not offered as revision authors.
- Monitor, retro and decision-hygiene Claude runs fail on an error result
event, like execute.
- A no-op settings.json update keeps the user's bytes (`{}` is no longer
deleted when hooks are off).
- PostToolUse reports a background Agent launch as an acknowledgement,
not a result.
- Individually backticked member Tools (`Read`, `Grep`) are accepted.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Lockout fields come from a repository file and from free text typed with `squad lockout`. Before they reach the coordinator (SessionStart, SubagentStart, PreToolUse, PostToolUse) they are flattened to one line, stripped of markup and code delimiters, bounded, and the reason is quoted as a JSON string; member IDs that are not a-z0-9- are dropped (code scanning review on #2450). Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
`.squad/config.json` belongs to the repository, so `watch.claudeFlags` from that file could add `--mcp-config .mcp.json` (or settings, plugins, extra directories, another agent) and undo the Claude preset's squad_state-only MCP config during unattended runs. The file may now set only --permission-mode, --model, --fallback-model, --effort, --max-turns and the allowed/disallowed tool lists, with validated values; anything else fails config loading with a clear error. --claude-flags on the command line is the user's own and stays unrestricted (code scanning review on #2450). Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…s data SessionStart context included routing.md work types, charter roles and the Ralph circuit breaker's model names verbatim; all are repository text. They now go through the same inert() handling as lockout fields: work types and model names are quoted, roles flattened, and routes name only roster members. Charters are read with the team-directory containment guard (code scanning review on #2450). Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
| to: [...new Set(ids(r.routeTo.toLowerCase().split(/[\s,/&+]+/).map((t) => t.replace(/^@/, ''))).filter((id) => known.has(id)))], | ||
| })) | ||
| .filter((r) => r.work && r.to.length > 0); | ||
| if (routes.length > 0) lines.push(`Routing (work type, as written → member): ${routes.map((r) => `${JSON.stringify(r.work)} → ${r.to.join(', ')}`).join('; ')}.`); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Not changed; leaving this open for a human reviewer. The Squad coordinator is designed to read routing.md, member charters and team.md from the repository, because that's how it routes work, so the hook context adds no capability it lacks. It's a short summary of the same files, and since 0ee75de and d23f573 every free-text field in it is flattened, stripped of markup and code delimiters, length-capped and quoted as a JSON string. Routes name only roster members, and IDs are checked against a-z0-9-. Dropping roles, work types and the reviewer's reason would remove information the coordinator needs (the reason tells the successor what to fix) without removing any attack path.
🤖 Addressed by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
Tool-list flags (--allowedTools, --disallowedTools and their dashed forms) can widen what Claude Code may run, so watch.claudeFlags in .squad/config.json may no longer set them; they must come from --claude-flags on the command line (code scanning review on #2450). Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
| to: [...new Set(ids(r.routeTo.toLowerCase().split(/[\s,/&+]+/).map((t) => t.replace(/^@/, ''))).filter((id) => known.has(id)))], | ||
| })) | ||
| .filter((r) => r.work && r.to.length > 0); | ||
| if (routes.length > 0) lines.push(`Routing (work type, as written → member): ${routes.map((r) => `${JSON.stringify(r.work)} → ${r.to.join(', ')}`).join('; ')}.`); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Same finding as the open thread on this line (comment 4519849501), and the same answer: the coordinator reads routing.md and the charters directly by design. The hook context is a quoted, flattened, length-capped summary of those files, and routes name only roster members. I'm leaving it open alongside that thread for a human reviewer.
🤖 Addressed by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
…gine The cell stays n/a (the workflows run in GitHub Actions, so the local host is irrelevant), but the mechanism no longer implies Copilot is the only engine: gh-aw ships `engine: claude`, Squad does not ship a workflow for it yet, and the notes record what one would need (`engine.args` with `--agent squad`, `bare: false`) with a link to the #2438 research. Refs #2442 Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
Directory names under .squad/agents/ reached SessionStart context as-is; names outside a-z0-9- are now ignored, matching member IDs elsewhere (code scanning review on #2450). Co-Authored-By: Claude Opus 5.5 <[email protected]>
| // individually quoted names (`Read`, `Grep`) is left for the per-token pass. | ||
| const value = m[2]!.trim().replace(/^`([^`]*)`$/, '$1'); | ||
| if (label === 'tools') { | ||
| const tools = value.split(',').map((t) => t.trim().replace(/^`(.*)`$/, '$1')).filter(Boolean); |
There was a problem hiding this comment.
The reason will be displayed to describe this comment to others. Learn more.
Not changed; leaving this open for a human reviewer. In a Claude Code subagent file, tools: is an allowlist that narrows the session's tools. A subagent without it inherits every tool the session has, so - **Tools:** Bash can only restrict a member, never grant more than it would get by default. Permission to actually run a tool is still decided by the session's permission mode and rules; per charter §13.1 these fields are runtime config, not authorization. Invalid names are already rejected and reported (TOOL_RE), and an empty or rejected list falls back to inheriting. Limiting the allowed values to a fixed list of "safe" tools would only stop teams from narrowing their members (for example a read-only Scribe).
🤖 Addressed by Claude Code
Sorry, something went wrong.
There was an error while loading. Please reload this page.
There was an error while loading. Please reload this page.
…agent-sdk-harness The only conflict was the generated host-feature-matrix.md; it is regenerated from the auto-merged matrix JSON, which keeps both sides (experimental-backend.copilot validated-live with its live run, and ralph-cli-triage-watch.claude supported from #2450). Co-Authored-By: Claude Opus 5.5 <[email protected]>
There was an error while loading. Please reload this page.
Successfully merging this pull request may close these issues.
Claude host PR 3: Claude projection v2 (member subagents, skills, hooks, watch preset) (#2438 Phases 2, 3, 4, 6)
There was an error while loading. Please reload this page.