You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 344705b
Browse filesBrowse the repository at this point in the historyBrowse files
feat(claude): Claude projection v2: member subagents, skills, governance hooks, watch preset (#2450)
* feat(claude): project each team member as a Claude Code subagent
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>
* feat(claude): project skills and load coordinator sections on demand
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>
* feat(claude): opt-in advisory governance hooks and durable reviewer lockouts
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>
* feat(watch): built-in Claude Code runner for squad watch --execute
`--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>
* docs: move the Claude benchmark proposal to an issue
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>
* docs(ralph): list --agent-preset and --claude-flags in the watch flags table
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* feat(claude): Claude projection v2 with byte-preserving rollback
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>
* fix(claude): US spelling in spec; keep tool free text out of hook context
- 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>
* fix(claude): address review of Claude projection v2
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>
* fix(claude): pass lockout text to hook context as inert data
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>
* fix(watch): limit repository-supplied claudeFlags to safe flags
`.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>
* fix(claude): pass routing, roles and circuit models to hook context as 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>
* fix(watch): keep tool lists out of repository-supplied claudeFlags
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>
* docs(matrix): re-evaluate gh-aw.claude now that gh-aw has a Claude engine
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>
* fix(claude): hook roster lists only valid member IDs
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>
---------
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Claude Code: opt-in advisory governance hooks. With `"claudeHooks": "advisory"` in `.squad/config.json`, `squad upgrade --client claude` adds Squad hooks to `.claude/settings.json`, keeping your other settings and hooks. The hooks give the coordinator session context, warn a locked-out member who edits work under review, add a handoff summary after each member finishes, and remind the coordinator to run Scribe. They never block a tool call. New `squad lockout` command records reviewer lockouts in `.squad/governance/lockouts.json`, and the new `squad hook claude <Event>` command runs the hooks.
Claude Code: each team member, built-ins included, is projected as its own subagent in `.claude/agents/<member>.md`, generated from its charter. Model, reasoning effort and the new `X-squad-host-claude` charter extension (`Tools`, `Isolation`) map onto the subagent frontmatter, and the Claude coordinator now routes to named members and applies per-spawn model selection. Squad never overwrites a user-authored file at a member path (the result is reported as `skipped`), removes the file of a member whose charter is gone, and removes every generated member file on rollback. `squad cast` refreshes the member files when `claude` is configured. Projections for other hosts are unchanged.
The Claude Code projection is now v2 (`CLAUDE_PROJECTION_VERSION`): member subagents, skills and the opt-in `settings.json` hooks ship as one version, and every generated Claude Markdown file states it in its generated-file note. v1 files are still recognised as Squad-owned and upgraded in place. Rollback of the `CLAUDE.md`, `AGENTS.md` and `GEMINI.md` marker blocks now restores the original bytes exactly, including files that ended without a newline or with a blank line.
Claude Code: Squad's template skills are projected as native skills in `.claude/skills/`, except where a team skill of the same name exists in `.squad/skills/`. The Claude coordinator now loads Init Mode, Ralph mode, ceremonies, GitHub Issues mode and PRD mode on demand from generated `squad-coordinator-*` skills instead of carrying them in its always-loaded prompt. The digest for other hosts and `.github/agents/squad.agent.md` are unchanged.
`squad watch --execute` gains a built-in Claude Code runner. `--agent-preset claude` (or `watch.agentPreset: "claude"`) runs each round as `claude -p <prompt> --agent squad --output-format stream-json --verbose` with a private `squad_state`-only MCP config (never the repository's `.mcp.json`), preflights the projected coordinator and the `claude` CLI, and treats an error `result` event as a failed round, including monitor, retro and decision-hygiene runs. Execute mode defaults to `--permission-mode bypassPermissions`; `--claude-flags` overrides it. `watch.claudeFlags` in `.squad/config.json` is limited to model, permission-mode, effort and turn-limit flags. The default Copilot runner is unchanged.
| Kiro (`kiro`) |`.kiro/steering/squad.md`|`.kiro/settings/mcp.json`|`.kiro/agents/squad.json`, Kiro spec and steering hooks | Kiro agent or spec execution hook |
294
294
| OpenCode (`opencode`) |`.opencode/agent/squad.md`|`opencode.json`| host agent and MCP definition blocks in `opencode.json`| OpenCode agent execution entry declared in `opencode.json`|
295
295
| Cursor (`cursor`) |`.cursor/agents/squad.md`|`.cursor/mcp.json`|`.cursor/rules/squad.mdc`| Cursor agent dispatch or inline agent run with projected rules |
@@ -300,6 +300,16 @@ These file paths are the portable contract. A host-specific installer may
300
300
write additional generated files, but it may not move the canonical anchor
301
301
without changing the projection version.
302
302
303
+
Projection versions are per host. The Claude Code projection is at **v2**
304
+
(`CLAUDE_PROJECTION_VERSION`): v1 wrote the coordinator, `.mcp.json`, the
305
+
`CLAUDE.md` block and the `.gitignore` lines; v2 adds one subagent per member,
306
+
the template and coordinator skills, and the opt-in `settings.json` hooks.
307
+
Every generated Claude Markdown file states its version in the generated-file
308
+
note (`… Claude projection v2.`). The note keeps the v1 wording as a prefix, so
309
+
`squad upgrade` still recognizes v1 files as Squad-owned and replaces them in
310
+
place. `settings.json` handlers are identified by their `hook claude <Event>`
311
+
args instead, because JSON has no comments.
312
+
303
313
The `submit` column describes the host execution primitive only. It is not the
304
314
portable conversation wire contract. MCP-backed projections are still host
305
315
transport details behind the shared backend semantics.
@@ -360,7 +370,73 @@ detail inside the harness adapter rather than a different workspace contract.
360
370
361
371
- agent anchor: `.claude/agents/squad.md`
362
372
- MCP config: `.mcp.json`
363
-
- support files: `CLAUDE.md`
373
+
- support files: `CLAUDE.md`, one member subagent `.claude/agents/<id>.md`
374
+
per charter in `.squad/agents/<id>/charter.md` (built-ins included), and
375
+
skills in `.claude/skills/<name>/SKILL.md`
376
+
377
+
The skills are Squad's template skills (from `.squad/templates/skills/`,
378
+
except where a team skill of the same name exists in `.squad/skills/`, which
379
+
keeps its precedence) and the coordinator's on-demand `squad-coordinator-*`
380
+
skills. The Claude coordinator digest replaces core-protocol items 0 (Init
`X-squad-host-claude` is a charter extension (charter v0.1 §8: namespace
400
+
`squad`, name `host-claude`). Its values are runtime configuration, not
401
+
authorization (charter v0.1 §13.1). A preference the projection cannot apply
402
+
(a non-Claude model, an invalid extension value, or `long_context` without a
403
+
long-context Claude model) is recorded in a comment in the generated file
404
+
rather than dropped silently (execution preferences v0.1 §6).
405
+
406
+
Governance hooks are opt-in. With `"claudeHooks": "advisory"` in
407
+
`.squad/config.json`, the projection adds one Squad handler per event to
408
+
`.claude/settings.json`. Each handler is an exec-form command (no shell) that
409
+
runs the MCP launch spec with `hook claude <Event>` in place of `state-mcp`.
410
+
The handlers are:
411
+
412
+
| Event | Matcher | Effect |
413
+
|---|---|---|
414
+
|`SessionStart`, `SubagentStart`|`squad` (SubagentStart only) | For the coordinator only: adds context with the CLI version the `squad_state` bridge must match, the roster, routing, active reviewer lockouts and an open Ralph circuit breaker |
415
+
|`PreToolUse`|`Edit\|MultiEdit\|Write\|NotebookEdit`| A member listed in an active lockout that edits a path the subject covers gets a warning, shown to the user and to the model |
416
+
|`PostToolUse`|`Agent\|Task`| After the coordinator spawns a member: adds a `squad-coordination-handoff/v0.1` envelope with structured fields only (`result` when the call finished; `acknowledgement` for a background launch, `status: "async_launched"`, which has not finished), a reminder to record decisions and run the reviewer gate, and the member's lockout state |
417
+
|`Stop`| none | For the coordinator, once per stop (`stop_hook_active` is honoured): asks for Scribe when `decisions/inbox/` has entries, and reports an open Ralph circuit breaker |
418
+
419
+
The hooks are advisory: no handler returns a `permissionDecision` or blocks a
420
+
stop, so they never grant or deny a tool call (governance-review v0.1 §10).
421
+
A handler that fails or finds hooks turned off prints nothing and exits 0.
422
+
The decisions inbox is read from disk, so a team on a non-local state backend
423
+
gets no Scribe reminder from `Stop`.
424
+
425
+
Reviewer lockouts are recorded durably in
426
+
`<squadDir>/governance/lockouts.json` by `squad lockout reject|assign|submit|approve|override|status`.
427
+
That command implements the governance-review v0.1 §6 states (`author-locked`,
428
+
`revision-assigned`, `revision-submitted`, `cleared`, `deadlocked`). An
429
+
override needs an authority (the user, or a member listed in
430
+
`governance.authorities` in `config.json`) and a reason. Revision authors are
431
+
the members with a charter, except the coordinator, Scribe, Ralph, Rai and
432
+
Fact Checker, whose charters exclude revision pairing. Each command reads,
433
+
transitions and writes the record under an interprocess lock, so concurrent
434
+
commands keep every transition. A `governance/` directory or file that resolves
435
+
outside the team directory is refused.
436
+
437
+
Projected Claude files never copy content from outside the team directory: a
438
+
charter, `routing.md` or template `SKILL.md` that resolves outside it through a
439
+
symlink is skipped.
364
440
365
441
### 7.2 `submit`
366
442
@@ -381,8 +457,9 @@ run identity.
381
457
### 7.3 `projectWorkspace`
382
458
383
459
The adapter reports the repository root, current working directory, and the
384
-
pair `.claude/agents/squad.md` plus `CLAUDE.md` so the broker can verify that
385
-
the projected host files are in sync with the portable Squad contract.
460
+
pair `.claude/agents/squad.md` plus `CLAUDE.md`, with the member subagents
461
+
under `supportFiles`, so the broker can verify that the projected host files
462
+
are in sync with the portable Squad contract.
386
463
387
464
## 8. Kiro projection
388
465
@@ -512,11 +589,25 @@ Companion-file ownership is explicit:
512
589
-`.claude/worktrees/` integration adds Squad-owned `.gitignore` lines under
513
590
an ID-scoped `# squad:claude` comment; rollback removes that comment and the
514
591
listed lines directly beneath it, and lines the user already had stay;
592
+
-`.claude/agents/<id>.md` member subagents and `.claude/skills/<name>/SKILL.md`
593
+
skills are Squad-managed only while they
594
+
carry the generated-file comment: a user-authored file at the same path is
595
+
never overwritten or removed (the apply result is `skipped`). Upgrade
596
+
removes the generated file of a member whose charter is gone (or of a skill
597
+
that is no longer projected), and rollback removes every generated file;
598
+
-`.claude/settings.json` is user-owned. Squad owns only its hook handlers,
599
+
identified by args ending in `hook claude <Event>`. Upgrade replaces those
600
+
handlers and keeps every other setting and hook. Turning `claudeHooks` off
601
+
removes them on the next upgrade. Rollback removes them and restores the
602
+
remaining JSON, and deletes the file only when nothing else was in it.
603
+
With hooks off and no settings file, nothing is written;
515
604
- the `CLAUDE.md` integration is a marker block between
516
605
`<!-- squad:begin (managed by Squad; do not edit between markers) -->` and
517
606
`<!-- squad:end -->`;
518
607
-`AGENTS.md` and `GEMINI.md` integrations are marker-scoped and therefore use
519
-
byte-preserving rollback outside those managed regions.
608
+
byte-preserving rollback outside those managed regions. A block is appended after one blank line, and keeps
609
+
the file's missing final newline missing, so removing it restores the
610
+
original bytes however the file ended.
520
611
521
612
Merge and upgrade behavior follows the same rule: full ownership allows
522
613
replacement with the current projection version, while marker-scoped ownership
|`--max-rounds N`| Stop after N completed rounds |`squad watch --max-rounds 20`|
198
198
|`--max-duration D`| Stop after elapsed time; finish an active round first |`squad watch --max-duration 8h`|
199
199
|`--claims <none\|git-ref>`| Claim each issue before dispatch (Git ref compare-and-swap on `origin`) so several watchers never work on the same issue. Default `none`. Config: `watch.claims` (`"git-ref"` or `{ "provider": "git-ref", "ttlMs", "skewMarginMs", "remote", "refPrefix" }`); the flag wins. See ADR-002. |`squad watch --execute --claims git-ref`|
200
200
|`--copilot-flags "..."`| Pass extra flags to Copilot CLI |`squad watch --execute --copilot-flags "--model gpt-5.6-luna"`|
201
+
|`--agent-preset <copilot\|claude>`| Runner for each round: `copilot` (default) or `claude` (Claude Code). Config: `watch.agentPreset`. See [Claude Code runner](#claude-code-runner---agent-preset-claude). |`squad watch --execute --agent-preset claude`|
202
+
|`--claude-flags "..."`| Flags for the `claude` preset; replaces the execute-mode default `--permission-mode bypassPermissions`. Config: `watch.claudeFlags`. |`squad watch --execute --agent-preset claude --claude-flags "--permission-mode acceptEdits"`|
201
203
202
204
With claims on, each round report adds a claims line when anything happened (for example `🔒 Claims (git-ref): won 2 · contended 1 · released 2 (completed 2)`): claims won, held by another watcher (`contended`), `unavailable`, `fenced` (taken over while held), `lost` (not renewed before expiry; agent killed), `released` by outcome, and `implausible` records taken over. `squad watch --health` shows the same counters since startup when the watch records a PID file. With an OTLP endpoint (`OTEL_EXPORTER_OTLP_ENDPOINT`) or `SQUAD_TELEMETRY=1`, they are also emitted as OpenTelemetry counters `squad.watch.claims.{acquired,contended,unavailable,fenced,lost,released,implausible_takeover}` with attributes `claim.provider` and, for `released`, `claim.outcome`. No issue numbers, hostnames, or actors are recorded. With `none`, output is unchanged. To run watchers on several machines or pods, see [Multi-Machine Watch with Work Claims](../scenarios/multi-machine-watch.md).
203
205
@@ -259,6 +261,43 @@ When all features are enabled, each round follows this cycle:
259
261
6.**Monitor**: Scan Teams/email for new actionable items
260
262
7.**Housekeep**: Check for retro, merge decision inbox if needed
261
263
8.**Report**: Log round summary, sleep until next interval
264
+
### Claude Code runner: `--agent-preset claude`
265
+
266
+
By default `--execute` runs each round through the Copilot CLI. To run it
267
+
through Claude Code instead, project the team for Claude and pick the preset:
268
+
269
+
```bash
270
+
squad upgrade --client claude
271
+
squad watch --execute --agent-preset claude
272
+
```
273
+
274
+
Or set it once in `.squad/config.json`:
275
+
276
+
```json
277
+
{ "watch": { "agentPreset": "claude" } }
278
+
```
279
+
280
+
Each round runs `claude -p "<prompt>" --agent squad --output-format stream-json
281
+
--verbose`, so the projected Squad coordinator handles the issues. The watcher
282
+
passes `--mcp-config` with a private config that holds only `squad_state`,
283
+
resolved by the `squad` CLI from its own install. It never passes your
284
+
repository's `.mcp.json`, so any other project MCP servers still need Claude
285
+
Code's usual approval. Preflight fails if `.claude/agents/squad.md` or the
286
+
`claude` CLI is missing. A run that exits cleanly but reports an error in its
287
+
final `result` event (for example `error_max_turns`) counts as a failed round;
288
+
this applies to monitor, retro and decision-hygiene runs too.
289
+
290
+
Execute mode adds `--permission-mode bypassPermissions` by default, the
291
+
counterpart of Copilot's `--yolo`. Pass your own flags with
0 commit comments