Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/claude-governance-hooks.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@bradygaster/squad-sdk": minor
"@bradygaster/squad-cli": minor
---

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.
6 changes: 6 additions & 0 deletions .changeset/claude-member-subagents.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@bradygaster/squad-sdk": minor
"@bradygaster/squad-cli": minor
---

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.
5 changes: 5 additions & 0 deletions .changeset/claude-projection-v2.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bradygaster/squad-sdk": minor
---

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.
5 changes: 5 additions & 0 deletions .changeset/claude-skills-projection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bradygaster/squad-sdk": minor
---

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.
5 changes: 5 additions & 0 deletions .changeset/claude-watch-preset.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@bradygaster/squad-cli": minor
---

`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.
101 changes: 96 additions & 5 deletions docs/specification/client-harness-adapters-v0.2.md
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ distinct from negotiated `effectiveCapabilities`.
| Host (`ClientId` / `hostKind`) | Agent anchor | MCP config | Support files | `submit` projection |
|---|---|---|---|---|
| GitHub Copilot (`copilot` / `github-copilot`) | `.github/agents/squad.agent.md` | `.mcp.json` | `.github/copilot-instructions.md` when present | `create_session`, `task`, or `runSubagent` depending on surface |
| Claude Code (`claude` / `claude-code`) | `.claude/agents/squad.md` | `.mcp.json` | `CLAUDE.md` marker block, `.gitignore` `# squad:claude` lines | Claude `Agent` subagent tool |
| Claude Code (`claude` / `claude-code`) | `.claude/agents/squad.md` | `.mcp.json` | `CLAUDE.md` marker block, `.gitignore` `# squad:claude` lines, `.claude/agents/<member>.md`, `.claude/skills/<name>/SKILL.md`, opt-in `.claude/settings.json` hooks | Claude `Agent` subagent tool |
| 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 |
| 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` |
| Cursor (`cursor`) | `.cursor/agents/squad.md` | `.cursor/mcp.json` | `.cursor/rules/squad.mdc` | Cursor agent dispatch or inline agent run with projected rules |
Expand All @@ -300,6 +300,16 @@ These file paths are the portable contract. A host-specific installer may
write additional generated files, but it may not move the canonical anchor
without changing the projection version.

Projection versions are per host. The Claude Code projection is at **v2**
(`CLAUDE_PROJECTION_VERSION`): v1 wrote the coordinator, `.mcp.json`, the
`CLAUDE.md` block and the `.gitignore` lines; v2 adds one subagent per member,
the template and coordinator skills, and the opt-in `settings.json` hooks.
Every generated Claude Markdown file states its version in the generated-file
note (`… Claude projection v2.`). The note keeps the v1 wording as a prefix, so
`squad upgrade` still recognizes v1 files as Squad-owned and replaces them in
place. `settings.json` handlers are identified by their `hook claude <Event>`
args instead, because JSON has no comments.

The `submit` column describes the host execution primitive only. It is not the
portable conversation wire contract. MCP-backed projections are still host
transport details behind the shared backend semantics.
Expand Down Expand Up @@ -360,7 +370,73 @@ detail inside the harness adapter rather than a different workspace contract.

- agent anchor: `.claude/agents/squad.md`
- MCP config: `.mcp.json`
- support files: `CLAUDE.md`
- support files: `CLAUDE.md`, one member subagent `.claude/agents/<id>.md`
per charter in `.squad/agents/<id>/charter.md` (built-ins included), and
skills in `.claude/skills/<name>/SKILL.md`

The skills are Squad's template skills (from `.squad/templates/skills/`,
except where a team skill of the same name exists in `.squad/skills/`, which
keeps its precedence) and the coordinator's on-demand `squad-coordinator-*`
skills. The Claude coordinator digest replaces core-protocol items 0 (Init
Mode and casting), 9 (Ralph mode), 15 (Ceremonies), 18 (GitHub Issues mode)
and 19 (PRD mode) with stubs that keep each trigger and the rules that must
hold before the skill is loaded; the full item text moves verbatim into the
matching skill. The shared digest for other hosts and
`.github/agents/squad.agent.md` are unchanged. Skill files remain untrusted
data (core-protocol item 17).

Member subagents map charter fields onto Claude Code frontmatter:

| Charter field | Frontmatter |
|---|---|
| `Identity: ID` (or the charter directory name) | `name` |
| `Identity: Purpose` (or name and role), plus the member's `routing.md` work types | `description` |
| `Model: Preferred` | `model`, only for a Claude model or alias; omitted for `auto` |
| `Model: Reasoning Effort` | `effort`; omitted for `auto` |
| `X-squad-host-claude: Tools` | `tools` |
| `X-squad-host-claude: Isolation` (`worktree`) | `isolation` |

`X-squad-host-claude` is a charter extension (charter v0.1 §8: namespace
`squad`, name `host-claude`). Its values are runtime configuration, not
authorization (charter v0.1 §13.1). A preference the projection cannot apply
(a non-Claude model, an invalid extension value, or `long_context` without a
long-context Claude model) is recorded in a comment in the generated file
rather than dropped silently (execution preferences v0.1 §6).

Governance hooks are opt-in. With `"claudeHooks": "advisory"` in
`.squad/config.json`, the projection adds one Squad handler per event to
`.claude/settings.json`. Each handler is an exec-form command (no shell) that
runs the MCP launch spec with `hook claude <Event>` in place of `state-mcp`.
The handlers are:

| Event | Matcher | Effect |
|---|---|---|
| `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 |
| `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 |
| `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 |
| `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 |

The hooks are advisory: no handler returns a `permissionDecision` or blocks a
stop, so they never grant or deny a tool call (governance-review v0.1 §10).
A handler that fails or finds hooks turned off prints nothing and exits 0.
The decisions inbox is read from disk, so a team on a non-local state backend
gets no Scribe reminder from `Stop`.

Reviewer lockouts are recorded durably in
`<squadDir>/governance/lockouts.json` by `squad lockout reject|assign|submit|approve|override|status`.
That command implements the governance-review v0.1 §6 states (`author-locked`,
`revision-assigned`, `revision-submitted`, `cleared`, `deadlocked`). An
override needs an authority (the user, or a member listed in
`governance.authorities` in `config.json`) and a reason. Revision authors are
the members with a charter, except the coordinator, Scribe, Ralph, Rai and
Fact Checker, whose charters exclude revision pairing. Each command reads,
transitions and writes the record under an interprocess lock, so concurrent
commands keep every transition. A `governance/` directory or file that resolves
outside the team directory is refused.

Projected Claude files never copy content from outside the team directory: a
charter, `routing.md` or template `SKILL.md` that resolves outside it through a
symlink is skipped.

### 7.2 `submit`

Expand All @@ -381,8 +457,9 @@ run identity.
### 7.3 `projectWorkspace`

The adapter reports the repository root, current working directory, and the
pair `.claude/agents/squad.md` plus `CLAUDE.md` so the broker can verify that
the projected host files are in sync with the portable Squad contract.
pair `.claude/agents/squad.md` plus `CLAUDE.md`, with the member subagents
under `supportFiles`, so the broker can verify that the projected host files
are in sync with the portable Squad contract.

## 8. Kiro projection

Expand Down Expand Up @@ -512,11 +589,25 @@ Companion-file ownership is explicit:
- `.claude/worktrees/` integration adds Squad-owned `.gitignore` lines under
an ID-scoped `# squad:claude` comment; rollback removes that comment and the
listed lines directly beneath it, and lines the user already had stay;
- `.claude/agents/<id>.md` member subagents and `.claude/skills/<name>/SKILL.md`
skills are Squad-managed only while they
carry the generated-file comment: a user-authored file at the same path is
never overwritten or removed (the apply result is `skipped`). Upgrade
removes the generated file of a member whose charter is gone (or of a skill
that is no longer projected), and rollback removes every generated file;
- `.claude/settings.json` is user-owned. Squad owns only its hook handlers,
identified by args ending in `hook claude <Event>`. Upgrade replaces those
handlers and keeps every other setting and hook. Turning `claudeHooks` off
removes them on the next upgrade. Rollback removes them and restores the
remaining JSON, and deletes the file only when nothing else was in it.
With hooks off and no settings file, nothing is written;
- the `CLAUDE.md` integration is a marker block between
`<!-- squad:begin (managed by Squad; do not edit between markers) -->` and
`<!-- squad:end -->`;
- `AGENTS.md` and `GEMINI.md` integrations are marker-scoped and therefore use
byte-preserving rollback outside those managed regions.
byte-preserving rollback outside those managed regions. A block is appended after one blank line, and keeps
the file's missing final newline missing, so removing it restores the
original bytes however the file ended.

Merge and upgrade behavior follows the same rule: full ownership allows
replacement with the current projection version, while marker-scoped ownership
Expand Down
41 changes: 40 additions & 1 deletion docs/src/content/docs/features/ralph.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,13 +191,15 @@ All new features are **opt-in** and disabled by default. Existing `squad watch`

| Flag | Description | Example |
|------|-------------|---------|
| `--execute` | Enable work execution (spawn Copilot to work on issues) | `squad watch --execute` |
| `--execute` | Enable work execution (spawn Copilot, or Claude Code with `--agent-preset claude`, to work on issues) | `squad watch --execute` |
| `--max-concurrent N` | Max parallel issues per round (default: 1) | `squad watch --execute --max-concurrent 3` |
| `--timeout N` | Per-issue timeout in minutes (default: 30) | `squad watch --execute --timeout 45` |
| `--max-rounds N` | Stop after N completed rounds | `squad watch --max-rounds 20` |
| `--max-duration D` | Stop after elapsed time; finish an active round first | `squad watch --max-duration 8h` |
| `--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` |
| `--copilot-flags "..."` | Pass extra flags to Copilot CLI | `squad watch --execute --copilot-flags "--model gpt-5.6-luna"` |
| `--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` |
| `--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"` |

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).

Expand Down Expand Up @@ -259,6 +261,43 @@ When all features are enabled, each round follows this cycle:
6. **Monitor**: Scan Teams/email for new actionable items
7. **Housekeep**: Check for retro, merge decision inbox if needed
8. **Report**: Log round summary, sleep until next interval
### Claude Code runner: `--agent-preset claude`

By default `--execute` runs each round through the Copilot CLI. To run it
through Claude Code instead, project the team for Claude and pick the preset:

```bash
squad upgrade --client claude
squad watch --execute --agent-preset claude
```

Or set it once in `.squad/config.json`:

```json
{ "watch": { "agentPreset": "claude" } }
```

Each round runs `claude -p "<prompt>" --agent squad --output-format stream-json
--verbose`, so the projected Squad coordinator handles the issues. The watcher
passes `--mcp-config` with a private config that holds only `squad_state`,
resolved by the `squad` CLI from its own install. It never passes your
repository's `.mcp.json`, so any other project MCP servers still need Claude
Code's usual approval. Preflight fails if `.claude/agents/squad.md` or the
`claude` CLI is missing. A run that exits cleanly but reports an error in its
final `result` event (for example `error_max_turns`) counts as a failed round;
this applies to monitor, retro and decision-hygiene runs too.

Execute mode adds `--permission-mode bypassPermissions` by default, the
counterpart of Copilot's `--yolo`. Pass your own flags with
`--claude-flags "--permission-mode acceptEdits --model sonnet"` (or
`watch.claudeFlags`) to replace that default. Because `.squad/config.json`
belongs to the repository, `watch.claudeFlags` may only set
`--permission-mode`, `--model`, `--fallback-model`, `--effort` and
`--max-turns`; tool lists and flags that change MCP servers, settings,
plugins, directories or the agent are refused there and must come from
`--claude-flags`. `--agent-cmd` still overrides the
preset, and `--dispatch-mode fleet` stays Copilot-only.

### Advanced: `--agent-cmd` (Hidden Flag)
For advanced users who know what they're doing:
```bash
Expand Down
Loading
Loading