Repository navigation
feat(claude): Claude projection v2: member subagents, skills, governance hooks, watch preset - #2450
Conversation
Phase 2 of #2442. Every charter in .squad/agents/ (built-ins included) becomes a managed .claude/agents/<id>.md. Charter model, reasoning effort and the X-squad-host-claude extension (Tools, Isolation) map onto the subagent frontmatter; config reasoning effort outranks the charter. - managed files can carry an ownership marker: user-authored files at the same path are skipped (new `skipped` apply action) and never removed - new `obsolete` projection entry removes generated files of members whose charter is gone, on upgrade and on rollback - the Claude dispatch section routes to named members and applies per-spawn model precedence via the Agent tool's per-call model - squad cast refreshes member files when claude is configured (local mode) - model-selection.claude flips to supported in the host feature matrix - spec 7.1/7.3/13 document the member files and the extension Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Phase 4 of #2442. Squad's template skills are projected into .claude/skills/<name>/SKILL.md (a team skill of the same name in .squad/skills/ keeps precedence, so its template is not projected), with the same ownership-marker rules as member subagents. The Claude coordinator digest replaces core-protocol items 0 (Init Mode), 9 (Ralph), 15 (Ceremonies), 18 (Issues) and 19 (PRD) with stubs that keep each trigger and its pre-load rules; the full item text moves verbatim into generated squad-coordinator-* skills. Other hosts' digests and .github/agents/squad.agent.md are unchanged. The parity tests check the Claude digest plus its skills. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ockouts With "claudeHooks": "advisory" in .squad/config.json, the Claude projection adds Squad hook handlers to .claude/settings.json (SessionStart, SubagentStart, PreToolUse, PostToolUse, Stop). They run `squad hook claude <Event>` and only add context or warnings; none returns a permissionDecision. User settings and hooks are preserved; turning hooks off or rolling back restores them byte for byte. `squad lockout` records governance-review §6 lockout state in .squad/governance/lockouts.json, which the PreToolUse hook reads to warn a locked-out member editing a covered path. Paths resolve through symlinks so the hook matches on macOS temp and symlinked checkouts. Part of #2442. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`--agent-preset claude` (or `watch.agentPreset: "claude"`) runs each round as `claude -p <prompt> --agent squad --mcp-config .mcp.json --output-format stream-json --verbose`. Preflight requires the projected coordinator and the claude CLI; an error `result` event counts as a failed round. Execute mode defaults to `--permission-mode bypassPermissions` (the counterpart of Copilot's --yolo); `--claude-flags` overrides it. The default Copilot runner, --agent-cmd precedence and Copilot-only fleet dispatch are unchanged. Flips ralph-cli-triage-watch.claude to supported in the host feature matrix. Refs #2442 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The design and the Sonnet 5.5 calibration results now live in #2449, so the proposal file is no longer needed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s table Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Bump the Claude Code projection once, to v2 (CLAUDE_PROJECTION_VERSION), for member subagents, skills and the opt-in settings.json hooks. Every generated Claude Markdown file states the version in its generated-file note; the v1 wording stays a prefix so v1 files are still recognised as Squad-owned and upgraded in place. Rollback tests (harness-adapters §15.7) snapshot the whole tree and require identical bytes after install, upgrade and rollback, including user content in every shared file and user-authored files at generated paths. They found that marker-block rollback (CLAUDE.md, AGENTS.md, GEMINI.md) added or dropped a newline when the file ended without one or with a blank line; upsertBlock and removeBlock now round-trip exactly. Also fixes regressions from earlier phases: `squad hook` leaves the main help (Claude Code invokes it), `lockout` fits in 80 columns, the help budget allows it, and the Init Mode scenario tests read Claude's coordinator together with the skills it loads. Refs #2442 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🟠 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)
|
🏗️ Architectural Review
Automated architectural review — informational only. |
🛫 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 |
Files Changed (46 files, +3322 −105)
| 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.
| } | ||
|
|
||
| /** 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.
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
…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 <noreply@anthropic.com>
There was a problem hiding this comment.
🟡 Changes recommended
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.
11 open issues
Protect lockout read-modify-write with an interprocess transaction · New Avoid bypassing approval for repository-controlled MCP servers · New Reject symlinked SKILL.md files outside the workspace · New Reject skill templates that resolve outside the team directory · New Reject symlinked governance directories outside the workspace · New Do not parse --json as the lockout status subject · New Validate Claude result events in the generic runner · New Preserve settings files when hook projection makes no changes · New Emit completion envelopes when background agents finish · New Preserve individually backticked tool names during parsing · New Exclude reviewer-only built-ins from revision author pools · New
What changed in this PR
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:
- Projects member charters and coordinator guidance into Claude-native agents and skills.
- Adds opt-in governance hooks and persistent reviewer-lockout commands.
- Adds the Claude watch preset and extends projection ownership, rollback coverage, and documentation.
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)
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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
`.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 <noreply@anthropic.com>
…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 <noreply@anthropic.com>
| 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.
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
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 <noreply@anthropic.com>
| 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.
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
…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 <noreply@anthropic.com>
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 <noreply@anthropic.com>
| // 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.
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
…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 <noreply@anthropic.com>


What
Claude projection v2 for Claude Code (#2442, part of epic #2438), shipped as one projection-version bump:
.squad/agents/compiles to.claude/agents/<id>.md, with model, effort, tools and isolation taken from the charter and its## X-squad-host-claudeextension..claude/agents/squad.mdloads them only when needed.claudeHooks: "advisory"mergessquad hook claude <Event>handlers into.claude/settings.jsonnext to the user's own hooks. A durable reviewer-lockout record (squad lockout) follows governance-review §6.squad watch --execute --agent-preset claude: runs each round asclaude -p … --agent squad --mcp-config .mcp.json --output-format stream-json --verbose. Copilot stays the default runner.CLAUDE_PROJECTION_VERSION = 2): every generated Claude Markdown file states the version. v1 files are still recognised as Squad-owned and are upgraded in place.Why
Closes #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
squad watch --executewithout a custom--agent-cmd.How
test/claude-projection-v2-rollback.test.tssnapshots the whole tree and requires identical bytes after install, upgrade and rollback. That found a bug in the marker-block code shared byCLAUDE.md,AGENTS.mdandGEMINI.md: rollback added or dropped a newline when a file ended without one or with a blank line. It's fixed inupsertBlockandremoveBlock. As a side effect, a file without a final newline now keeps having none after install.--permission-mode bypassPermissions, the counterpart of Copilot's--yolo, and--claude-flagsoverrides it.resultevent that reports an error counts as a failed round, even when the process exits 0.--agent-cmdstill wins over the preset, and fleet dispatch stays Copilot-only.ralph-cli-triage-watch.claudechanges from degraded to supported, and reviewer-lockout gains evidence. The generated page is regenerated and passes--check.Note on history: e33840c accidentally included
docs/proposals/claude-code-benchmark.md, and f7a75e8 deletes it again (its content moved to #2449). The net diff doesn't touch the file. A squash merge is recommended..changeset/claude-member-subagents.md,claude-skills-projection.md,claude-governance-hooks.md,claude-watch-preset.md,claude-projection-v2.md)PR Readiness Checklist
Branch & Commit
dev(notmain)devBuild & Test
npm run buildpasses (SDK and CLI built withtsc)npm testpasses: 13,241 passed and 34 failed locally on macOS. None of the failures is in code this PR touches:Path traversal blockedunder/var/folders, caused by the macOS/var→/private/varsymlink. They're in the memory, upstream, bridge and profile-guard tests.dev.Three regressions from earlier phases were found and fixed: the help-width gate, the help-length gate and the Claude Init Mode scenario tests. The suites covering this PR's code pass: 196 tests, plus 12 for the watch preset.
npm run lintpassesnpm run lint:eslintpasses (warnings only)Changeset
Docs
docs/src/content/docs/scenarios/client-compatibility.md: the Claude Code section, governance hooks, and the watch preset rowdocs/src/content/docs/features/ralph.md: a Claude Code runner section and flags-table rowsdocs/specification/client-harness-adapters-v0.2.md: §5 projection v2, §7.1 hooks and lockouts, and §13 ownership and rollbackExports
clientssubpath.Breaking Changes
None. Everything new is either generated only for
--client claudeor opt-in (claudeHooks,--agent-preset claude). The default Copilot projection and runner are unchanged. The only behaviour change outside Claude is the marker-block newline fix above.Waivers
None.
🤖 Generated with Claude Code