diff --git a/.changeset/add-rework-rate-metric.md b/.changeset/add-rework-rate-metric.md deleted file mode 100644 index 20d83e64c..000000000 --- a/.changeset/add-rework-rate-metric.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor ---- - -Add rework rate OTEL metrics (#265) — tracks PR revision patterns as the emerging 5th DORA metric diff --git a/.changeset/add-routing-to-export-import.md b/.changeset/add-routing-to-export-import.md deleted file mode 100644 index 14dbb9260..000000000 --- a/.changeset/add-routing-to-export-import.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -Add routing.md to squad export/import functionality - -The routing.md file is now included when exporting and importing Squad configurations. -This preserves the full routing context (tables, comments, principles) alongside the -structured routing rules that were already exported. diff --git a/.changeset/add-session-recovery-skill.md b/.changeset/add-session-recovery-skill.md deleted file mode 100644 index 53d80c9c1..000000000 --- a/.changeset/add-session-recovery-skill.md +++ /dev/null @@ -1,4 +0,0 @@ ---- ---- - -Add session-recovery skill for detecting and resuming interrupted Copilot CLI sessions diff --git a/.changeset/add-skill-script-loader.md b/.changeset/add-skill-script-loader.md deleted file mode 100644 index d36276e9f..000000000 --- a/.changeset/add-skill-script-loader.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor ---- - -Add SkillScriptLoader, handler types, and applySkillHandlers for executable skill handler scripts diff --git a/.changeset/ado-configurable-items.md b/.changeset/ado-configurable-items.md deleted file mode 100644 index b1b2e0cec..000000000 --- a/.changeset/ado-configurable-items.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor ---- - -ADO configurable work item types, area paths, and iteration support (#240) - -- Add `getAvailableWorkItemTypes(org, project)` for process template introspection -- Add `validateWorkItemType(org, project, typeName)` for pre-creation validation -- Add `WorkItemTypeInfo` interface for type metadata -- Enhance `AzureDevOpsAdapter` with instance-level `getAvailableWorkItemTypes()` and `validateWorkItemType()` methods -- Support optional `validateType` flag in `createWorkItem()` to check type before creation -- Enhance `squad init` to introspect available work item types and store `_availableTypes` hint in `.squad/config.json` -- Support `adoConfig` in `InitOptions` for explicit work item type, area path, and iteration path during init -- Graceful fallback to default types (User Story, Bug, Task) when az CLI is unavailable diff --git a/.changeset/apm-integration.md b/.changeset/apm-integration.md deleted file mode 100644 index 094f3102d..000000000 --- a/.changeset/apm-integration.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -feat: APM integration — squad skill publish/install + apm.yml in init - -Implements #824. Adds `squad skill publish/install/list` commands and generates `apm.yml` on `squad init`. diff --git a/.changeset/builtin-skills.md b/.changeset/builtin-skills.md deleted file mode 100644 index 30962cc2e..000000000 --- a/.changeset/builtin-skills.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -Ship 8 built-in skills with squad init/upgrade (#788) - -New skills distributed automatically on `squad init` and `squad upgrade`: -- **error-recovery** — graceful failure handling patterns -- **secret-handling** — credential safety and secrets management -- **git-workflow** — branch management and commit conventions -- **session-recovery** — checkpoint and recovery patterns -- **reviewer-protocol** — code review gate patterns -- **test-discipline** — test-first discipline and coverage -- **agent-collaboration** — multi-agent handoff patterns -- **squad-conventions** — (already shipped, now part of curated set) - -All skills are squad-owned (`overwriteOnUpgrade: true`) and update on upgrade. diff --git a/.changeset/cleanup-ceremony.md b/.changeset/cleanup-ceremony.md deleted file mode 100644 index 4a9a2631e..000000000 --- a/.changeset/cleanup-ceremony.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -Add cleanup watch capability for stale file housekeeping (#791) - -- New `cleanup` capability in the `housekeeping` phase -- Clears `.squad/.scratch/` (all ephemeral temp files) -- Archives orchestration-log and session-log entries older than 30 days -- Warns about stale decision inbox files (>7 days) -- Configurable: `everyNRounds` (default: 10), `maxAgeDays` (default: 30) -- 12 new tests diff --git a/.changeset/contamination-guard.md b/.changeset/contamination-guard.md deleted file mode 100644 index 29ed0ae95..000000000 --- a/.changeset/contamination-guard.md +++ /dev/null @@ -1,8 +0,0 @@ ---- ---- - -ci: add PR contamination prevention guard - -New diff-guard CI check warns when single-commit PRs touch 30+ files -(likely branch contamination). Updated copilot-instructions with branch -creation and staging safety rules. diff --git a/.changeset/cooperative-rate-limiting.md b/.changeset/cooperative-rate-limiting.md deleted file mode 100644 index 524a58109..000000000 --- a/.changeset/cooperative-rate-limiting.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor ---- - -feat: Cooperative rate limiting with predictive circuit breaker - -Added cooperative rate limiting patterns for multi-agent deployments: -- Traffic Light, Predictive Circuit Breaker, Priority Retry Windows -- Cooperative Token Pool for shared quota management - -Closes #515 diff --git a/.changeset/cross-squad-orchestration.md b/.changeset/cross-squad-orchestration.md deleted file mode 100644 index c22bde31a..000000000 --- a/.changeset/cross-squad-orchestration.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -Cross-squad orchestration — discovery, delegation, and manifest (#316). Adds manifest schema, `squad discover` / `squad delegate` commands, and runtime module for coordinating work across multiple Squad instances. diff --git a/.changeset/deprecate-tunnel-rc-repl.md b/.changeset/deprecate-tunnel-rc-repl.md deleted file mode 100644 index 93b3e3614..000000000 --- a/.changeset/deprecate-tunnel-rc-repl.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -Add deprecation warnings for tunnel, rc, and REPL commands. The interactive shell (no-args), `squad start`, `squad start --tunnel`, `squad rc`, and `squad rc-tunnel` now emit yellow deprecation notices pointing users to the GitHub Copilot CLI. No behavior changes — all commands still work. diff --git a/.changeset/docs-fork-contribution-workflow.md b/.changeset/docs-fork-contribution-workflow.md deleted file mode 100644 index 8d2d664ab..000000000 --- a/.changeset/docs-fork-contribution-workflow.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -docs: add fork contribution workflow to CONTRIBUTING.md - -Closes five gaps discovered during PR #217: -- Fork-first setup instructions (fork → clone → upstream remote) -- PR must target `dev` branch, not `main` (`gh pr create --base dev`) -- Changeset is a required step in the PR process checklist -- `bradygaster/dev` now correctly described as the PR target for all contributions -- New "Keeping Your Fork in Sync" section with rebase-on-upstream/dev instructions diff --git a/.changeset/docs-state-backends.md b/.changeset/docs-state-backends.md deleted file mode 100644 index 5378b0cef..000000000 --- a/.changeset/docs-state-backends.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Add user-facing documentation for state backends (local, orphan-branch, two-layer) diff --git a/.changeset/dual-mode-capabilities.md b/.changeset/dual-mode-capabilities.md deleted file mode 100644 index 497aeda5c..000000000 --- a/.changeset/dual-mode-capabilities.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -'@bradygaster/squad-sdk': minor ---- - -Add dual-mode deployment support for capabilities routing. - -New features: -- `SQUAD_POD_ID` env var for pod-specific capability manifests -- `SQUAD_DEPLOYMENT_MODE` env var (`agent-per-node` | `squad-per-pod`) -- Pod-specific manifest loading: `.squad/machine-capabilities-{podId}.json` -- Fallback chain: pod-specific → shared → user-home → null (opt-in) -- New exports: `getDeploymentMode()`, `getPodId()`, `DeploymentMode` type diff --git a/.changeset/error-recovery-skill.md b/.changeset/error-recovery-skill.md deleted file mode 100644 index ec48a85a3..000000000 --- a/.changeset/error-recovery-skill.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- -feat: add error-recovery skill for standard agent failure recovery patterns \ No newline at end of file diff --git a/.changeset/external-state.md b/.changeset/external-state.md deleted file mode 100644 index 9585a11d6..000000000 --- a/.changeset/external-state.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -Add external state storage — move .squad/ out of the working tree (#792) - -- New `stateLocation: 'external'` option in `.squad/config.json` -- `resolveExternalStateDir()` resolves state under the platform-specific global Squad directory (`resolveGlobalSquadPath()`) -- `deriveProjectKey()` generates a stable key from the repo path (cross-platform) -- `resolveSquadPaths()` honors external state location -- `squad externalize` moves state out, `squad internalize` moves it back -- State survives branch switches, invisible to `git status`, never pollutes PRs -- Thin `.squad/config.json` marker stays in repo (gitignored) -- Path traversal protection on projectKey -- 12 new tests diff --git a/.changeset/fact-checker-agent.md b/.changeset/fact-checker-agent.md deleted file mode 100644 index 7f20635d3..000000000 --- a/.changeset/fact-checker-agent.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -Add fact-checker as a built-in agent role (#789) - -- New `fact-checker` role in the engineering role catalog (emoji: 🔍, category: quality) -- Charter template at `templates/fact-checker-charter.md` with verification methodology -- Added to `AGENT_TEMPLATES` for init scaffolding -- Template manifest entry for init/upgrade distribution -- Routing patterns: fact-check, verify, validate, audit, double-check, hallucination, devil's advocate diff --git a/.changeset/fix-brady-bug.md b/.changeset/fix-brady-bug.md deleted file mode 100644 index edd91bb0e..000000000 --- a/.changeset/fix-brady-bug.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@bradygaster/squad-cli': patch -'@bradygaster/squad-sdk': patch ---- - -Fix hardcoded "Brady" in template files — LLMs now use actual git username instead of example name (closes #977) diff --git a/.changeset/fix-changelog-gate.md b/.changeset/fix-changelog-gate.md deleted file mode 100644 index 1d84acec2..000000000 --- a/.changeset/fix-changelog-gate.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Fix changelog-gate CI to accept .changeset/ files as alternative to direct CHANGELOG.md edits diff --git a/.changeset/fix-cli-prerelease-version-skill.md b/.changeset/fix-cli-prerelease-version-skill.md deleted file mode 100644 index 3125e4f50..000000000 --- a/.changeset/fix-cli-prerelease-version-skill.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@bradygaster/squad-cli": patch -"@bradygaster/squad-sdk": patch ---- - -fix: bump CLI version to 0.9.7-preview; align E2E skill and policy gate with CONTRIBUTING.md - -The insider publish workflow stamped `@bradygaster/squad-cli` at `0.9.6-build.4`, -which violates the prerelease version policy gate. Per CONTRIBUTING.md, the correct -local dev version is `{next-version}-preview`. - -- `packages/squad-cli/package.json`: `0.9.6-build.4` → `0.9.7-preview` -- All 4 copies of `e2e-template-testing/SKILL.md` (root `templates/`, - `packages/squad-sdk/templates/`, `packages/squad-cli/templates/`, - `.squad-templates/`): - - **Build commands** aligned with CONTRIBUTING.md (lines 253–256): use workspace - flags `npm run build -w packages/squad-sdk && npm run build -w packages/squad-cli` - and `npm link -w packages/squad-cli` instead of shell `cd` + bare `npm run build` - - **Version verify text** updated to version-agnostic `x.y.z-preview` placeholder - with an explicit note that the `-preview` suffix is required, linking to - CONTRIBUTING.md for the full local dev setup -- `.github/workflows/squad-ci.yml` — Prerelease Version Guard: relaxed regex from - `/-/` (any hyphen) to `/-/ && not /^\d+\.\d+\.\d+-preview$/` so the CONTRIBUTING.md- - sanctioned `-preview` suffix is allowed while all other prerelease tags (e.g. - `-build.4`, `-alpha`, `-beta`) are still blocked diff --git a/.changeset/fix-context-overflow-sentinel-1035.md b/.changeset/fix-context-overflow-sentinel-1035.md deleted file mode 100644 index 09eab3ac7..000000000 --- a/.changeset/fix-context-overflow-sentinel-1035.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@bradygaster/squad-cli": patch -"@bradygaster/squad-sdk": patch ---- - -fix: context overflow sentinel and coordinator size reduction (retroactive for #1035) - -`squad.agent.md` was ~95.8KB and could be silently dropped from context in long sessions, degrading the coordinator to vanilla Copilot with no safety rails. - -Changes shipped in PR #1035 (merged without changeset): - -- **Canary sentinel** — `SQUAD_COORDINATOR_CANARY_a8f3` token appended to `squad.agent.md`; `copilot-instructions.md` checks for it and warns if the coordinator was dropped from context -- **Coordinator slimming** — `squad.agent.md` reduced ~42% (95.8KB → ~55KB) by extracting to on-demand reference files: `spawn-reference.md`, `after-agent-reference.md`, `model-selection-reference.md`, `ralph-reference.md`, `worktree-reference.md`, `client-compatibility-reference.md` -- **Scribe charter extraction** — Scribe's inline section moved from `squad.agent.md` to a standalone `scribe-charter.md` -- **E2E skill overhaul** — Fast-fail rules, PII protection, anti-skip enforcement, live progress tracking comment (updated per step), duration tracking, Windows encoding fix, `--allow-all-tools` documentation, progressive verdicting, agent run time budget -- **Build fix** — CLI dep changed from `@bradygaster/squad-sdk: >=0.9.0` to `>=0.9.0-0` so npm workspace resolution uses the local prerelease package instead of a stale published version - -All 4 template locations synced: `.squad-templates/`, `templates/`, `packages/squad-cli/templates/`, `packages/squad-sdk/templates/`. - -Closes #1017 diff --git a/.changeset/fix-current-datetime-propagation.md b/.changeset/fix-current-datetime-propagation.md deleted file mode 100644 index 9b5a196c6..000000000 --- a/.changeset/fix-current-datetime-propagation.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@bradygaster/squad-cli': patch -'@bradygaster/squad-sdk': patch ---- - -Fix coordinator and Scribe templates so spawned agents receive and write the resolved current datetime instead of placeholder text. diff --git a/.changeset/fix-detect-squad-dir-zero-deps.md b/.changeset/fix-detect-squad-dir-zero-deps.md deleted file mode 100644 index ca9fb1396..000000000 --- a/.changeset/fix-detect-squad-dir-zero-deps.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(cli): revert detect-squad-dir to zero-dependency bootstrap - -The StorageProvider refactor (26047dc5) accidentally converted this bootstrap utility from raw node:fs to FSStorageProvider. This file runs before the SDK is loaded and must not depend on @bradygaster/squad-sdk. Adds regression guard test. diff --git a/.changeset/fix-dev-ci-failures.md b/.changeset/fix-dev-ci-failures.md deleted file mode 100644 index 8b1dee5ab..000000000 --- a/.changeset/fix-dev-ci-failures.md +++ /dev/null @@ -1,40 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix: restore CI green on dev — 25 regression fixes + 6 test corrections - -Commit `4ecc244` ("feat: Squad Remote Control") rewrote `cli-entry.ts` and -silently dropped multiple P0 bug fixes. Commit `72ffcb1` ("unified status -display") introduced a TUI regression in AgentPanel. This changeset restores -all dropped behaviour and corrects test expectations that never matched the -implementation. - -**Implementation regressions fixed (cli-entry.ts):** -- Bare semver output: `squad --version` now prints `0.x.y` not `squad 0.x.y` -- Whitespace args guard: `squad` / `squad ` shows brief help and exits 0 -- `NODE_NO_WARNINGS=1` set before first import to suppress ExperimentalWarning -- `squad doctor` hint restored in unknown-command error messages -- Help lines that exceeded 80 chars wrapped to continuation lines - -**Implementation regressions fixed (shell/index.ts):** -- First-run (no `.squad/`) on non-TTY now outputs a welcome/get-started message - instead of a TTY error, matching E2E test expectations - -**Implementation regressions fixed (AgentPanel.tsx):** -- Completion flash correctly shows `✓ Done`; was showing `✓ [IDLE]` because - the status-label condition was not gated on the flash state - -**Test corrections (expectations that never matched implementation):** -- `repl-ux.test.ts`: `toContain('ready')` → `toContain('[idle]')` -- `human-journeys.test.ts`: `Scaffold ready` → `Your team is ready`; - `copilot session` → `squad` -- `cli/init.test.ts` + `repl-ux-fixes.test.ts`: wrong gitattributes path fixed -- `ux-gates.test.ts`: two aspirational grouped-help tests replaced with `it.todo` -- `first-run-gating.test.ts`: banner spacer regex updated to match current source form -- `consult-command.feature`: expected text updated to match current CLI output -- `status-extended.feature`: exit code corrected (`1` → `0`) for non-squad dir -- `docs-build.test.ts`: `beforeAll` hook given explicit 30 s timeout to avoid - flaky timeout failures under parallel test execution -- `journey-next-day.test.ts`: added `tick(50)` between session saves to prevent - race condition when both sessions receive the same `lastActiveAt` timestamp diff --git a/.changeset/fix-doctor-casting-upgrade.md b/.changeset/fix-doctor-casting-upgrade.md deleted file mode 100644 index 636aa7682..000000000 --- a/.changeset/fix-doctor-casting-upgrade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Fix squad doctor and upgrade for insiders installs: add .squad/casting/ to ENSURE_DIRECTORIES, scaffold casting defaults from templates with permission-safe fallback, and clarify ESM warnings for global installs. diff --git a/.changeset/fix-export-import-blank-files.md b/.changeset/fix-export-import-blank-files.md deleted file mode 100644 index 4a27cfeef..000000000 --- a/.changeset/fix-export-import-blank-files.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -Fix export/import producing blank decisions.md and team.md files. Export now includes these files in the manifest, and import restores their content. diff --git a/.changeset/fix-externalized-state-paths.md b/.changeset/fix-externalized-state-paths.md deleted file mode 100644 index 972a96d7d..000000000 --- a/.changeset/fix-externalized-state-paths.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Fix runtime commands to correctly resolve externalized state paths diff --git a/.changeset/fix-five-bugs-dotted-repos.md b/.changeset/fix-five-bugs-dotted-repos.md deleted file mode 100644 index d488b2ec4..000000000 --- a/.changeset/fix-five-bugs-dotted-repos.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@bradygaster/squad-cli': patch -'@bradygaster/squad-sdk': patch ---- - -Fix 5 bugs: dotted repo names, icon spacing, board owner, charter passing, missing playbooks diff --git a/.changeset/fix-init-noargs-createteam.md b/.changeset/fix-init-noargs-createteam.md deleted file mode 100644 index ff673f4b6..000000000 --- a/.changeset/fix-init-noargs-createteam.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix: `/init` with no args now accepts follow-up message as cast prompt, and `createTeam` correctly creates `team.md`/`routing.md` in fresh projects - -Two related bugs in the TUI init flow: - -1. After `/init` (no args) showed guidance text, the user's follow-up message hit the "No Squad team found" guard instead of starting team casting. Fixed by tracking `awaitingInitPrompt` state in `App.tsx` and bypassing the team-file guard in `handleDispatch` when `skipCastConfirmation` is explicitly set. - -2. After confirming a team proposal, `createTeam` silently skipped creating `team.md` and `routing.md` in a fresh project (no `.squad/` directory), causing the coordinator to immediately say "no team yet" after showing "Team hired!". Fixed with else-branches that create both files from scratch when they don't exist. diff --git a/.changeset/fix-nap-archival-budget.md b/.changeset/fix-nap-archival-budget.md deleted file mode 100644 index 95461886a..000000000 --- a/.changeset/fix-nap-archival-budget.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(nap): account for separator newlines in decision archival budget - -The budget calculation in archiveDecisions() did not account for the newline -separators added during content reassembly. This caused the final recentContent -to exceed DECISION_THRESHOLD even after archival. Fix adds reassemblyOverhead -and per-entry separator bytes to the budget calculation. - -Closes #123 \ No newline at end of file diff --git a/.changeset/fix-nap-subprocess-cwd.md b/.changeset/fix-nap-subprocess-cwd.md deleted file mode 100644 index 11edb2947..000000000 --- a/.changeset/fix-nap-subprocess-cwd.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(cli): wire --team-root / SQUAD_TEAM_ROOT into squad resolution for nap, status, and cost commands (#734) - -Commands that resolve .squad/ now respect the SQUAD_TEAM_ROOT env var (set by --team-root flag), -fixing subprocess invocations (e.g. Copilot CLI bang commands) where process.cwd() differs from -the interactive shell. Also improves the nap error message to show the searched directory. diff --git a/.changeset/fix-onboarding-mode-bail.md b/.changeset/fix-onboarding-mode-bail.md deleted file mode 100644 index 49f63f71c..000000000 --- a/.changeset/fix-onboarding-mode-bail.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix: CLI no longer bails when configured is false; starts onboarding session instead (#843) diff --git a/.changeset/fix-p1-coordinator-bugs.md b/.changeset/fix-p1-coordinator-bugs.md deleted file mode 100644 index bb77c7543..000000000 --- a/.changeset/fix-p1-coordinator-bugs.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(coordinator): resolve externalized state, teamRoot, stale work, and cleanup loops - -Fixes 4 P1 coordinator bugs where squad.agent.md would incorrectly enter Init Mode -in satellite/externalized repos (#1116, #1127), agents would work on stale/closed items -(#1125), and spawned agents would loop infinitely in post-work cleanup (#1067). diff --git a/.changeset/fix-permission-contract.md b/.changeset/fix-permission-contract.md deleted file mode 100644 index c40727410..000000000 --- a/.changeset/fix-permission-contract.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch -"@bradygaster/squad-cli": patch ---- - -Fix permission handler to use `approve-once` instead of deprecated `approved` kind, aligning with Copilot CLI v1.0.54+ permission contract diff --git a/.changeset/fix-post-init-message.md b/.changeset/fix-post-init-message.md deleted file mode 100644 index 4c8a17d81..000000000 --- a/.changeset/fix-post-init-message.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Fix post-init message to recommend `copilot --agent squad` instead of deprecated `squad` command (closes #1034, closes #1007) diff --git a/.changeset/fix-readme-migration-guide-link.md b/.changeset/fix-readme-migration-guide-link.md deleted file mode 100644 index 84d732067..000000000 --- a/.changeset/fix-readme-migration-guide-link.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -docs: point README migration guide links to the published docs site \ No newline at end of file diff --git a/.changeset/fix-roster-sync.md b/.changeset/fix-roster-sync.md deleted file mode 100644 index 2fd31a766..000000000 --- a/.changeset/fix-roster-sync.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-sdk': patch ---- - -Sync squad.agent.md roster when agents added to team.md diff --git a/.changeset/fix-scribe-test-charter-path.md b/.changeset/fix-scribe-test-charter-path.md deleted file mode 100644 index 09a20428c..000000000 --- a/.changeset/fix-scribe-test-charter-path.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(ci): fix multiple CI test failures introduced by PR #1035 coordinator slimming - -PR #1035 extracted Scribe and spawn-template content out of `squad.agent.md` into -standalone reference files but did not update the CI tests. Two tests failed: - -**`test/ci/scribe-template.test.ts`** — was reading from `squad.agent.md` with anchors -that no longer exist. Fixed to read from `scribe-charter.md` with: -- Number- and format-agnostic end-marker in `extractScribeTaskBlock` -- Numbered-line assertions (verify phrases appear on actual `\d+.` list items) -- Corrected file header comment (HEALTH REPORT and size thresholds ARE present) -- New tests: HEALTH REPORT emission documented, Tier 1 (20KB) and Tier 2 (50KB) - archival thresholds documented (10 tests total, was 7) - -**`test/ci/datetime-template.test.ts`** — was counting `CURRENT_DATETIME:` lines in -`squad.agent.md` only, expecting ≥4. After slimming only 2 remain there; the rest -moved to `spawn-reference.md` and `after-agent-reference.md`. Fixed to combine all -coordinator-owned template files for spawn-template assertions. diff --git a/.changeset/fix-silent-agent-md-skip.md b/.changeset/fix-silent-agent-md-skip.md deleted file mode 100644 index 349139fcb..000000000 --- a/.changeset/fix-silent-agent-md-skip.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@bradygaster/squad-cli': patch -'@bradygaster/squad-sdk': patch ---- - -Warn when squad.agent.md template is missing during upgrade or init instead of silently skipping file creation. Adds `warnings` field to `InitResult` for structured error reporting. diff --git a/.changeset/fix-state-backend-upgrade-regressions.md b/.changeset/fix-state-backend-upgrade-regressions.md deleted file mode 100644 index be966c14b..000000000 --- a/.changeset/fix-state-backend-upgrade-regressions.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -"@bradygaster/squad-cli": patch -"@bradygaster/squad-sdk": patch ---- - -Fix state-backend and upgrade regressions (#1163, #1185, #1190, #1191, #1194) - -**Bug A (P0) — Permission contract mismatch** (#1191) -The Copilot SDK changed the valid permission result `kind` from `"approved"` to -`"approve-once"`. Squad was still returning `{ kind: 'approved' }`, causing all -agent sessions to fail permission checks immediately. Fixed in: -- `cli/shell/index.ts` — `approveAllPermissions` handler now returns `{ kind: 'approve-once' }` -- `adapter/types.ts` — `SquadPermissionRequestResult.kind` union includes `'approve-once'` -- `adapter/client.ts` — error hint updated to reference the correct `kind` value - -**Bug B (P1) — Hard-throw in `resolveStateBackend()` when explicit backend fails** (#1185, #1190) -When a backend configured in `config.json` failed to initialize (e.g., no git repo -available), Squad threw a fatal error and refused to start. Now always warns and -falls back to `local` so operators can fix config without losing work. - -**Bug C (P1) — Silent git-notes→two-layer migration** (#1163) -`normalizeBackendType()` silently mapped `'git-notes'` to `'two-layer'` with no -user notification. Now emits a `console.warn()` directing users to update their -`config.json`. - -**Bug F (P3) — Windows `toRelative()` drive-letter case mismatch** -`StateBackendStorageAdapter.toRelative()` used a simple string prefix comparison -after normalizing separators. On Windows, `C:\` vs `c:\` drive-letter case -differences caused the prefix check to fail, returning full absolute paths as -git-notes keys (corruption). Now uses `path.resolve()` and case-insensitive -comparison on `process.platform === 'win32'`. - -**Issue #1194 — Externalized state paths not followed by runtime commands** -Adds `effectiveSquadDir()` and `resolveStateDir()` helpers that follow the -`stateLocation: 'external'` marker in `.squad/config.json`. Updates `loop`, -`watch`, `plugin`, `doctor` commands and `shell` (lifecycle, coordinator, index) -to use the effective state dir for reading `team.md`, `routing.md`, `agents/`, -`plugins/`, and other state files. diff --git a/.changeset/fix-subcommand-help.md b/.changeset/fix-subcommand-help.md deleted file mode 100644 index 777cc7467..000000000 --- a/.changeset/fix-subcommand-help.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -Fix `squad --help` silently running the command instead of showing help (#1201) - -Previously, passing `--help` or `-h` after a subcommand (e.g. `squad init --help`, -`squad triage --help`, `squad doctor --help`) was silently dropped and the command -would execute for real — sometimes with destructive side effects (init scaffolded -files into the cwd, triage/watch started a polling loop). Only `squad loop --help` -and `squad state-mcp --help` were intercepting the flag. - -The CLI now intercepts `--help`/`-h` for every registered subcommand in one place -at the top of the router and prints command-specific help via a new -`printCommandHelp(cmd, version)` helper. Unrecognized commands fall back to a -friendly "see `squad help`" message. No side effects are triggered. diff --git a/.changeset/fix-team-root-all-commands.md b/.changeset/fix-team-root-all-commands.md deleted file mode 100644 index dfffaea34..000000000 --- a/.changeset/fix-team-root-all-commands.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Extend SQUAD_TEAM_ROOT to all resolveSquad() call sites for subprocess compatibility diff --git a/.changeset/fix-triage-label-slug.md b/.changeset/fix-triage-label-slug.md deleted file mode 100644 index 60fb4ec81..000000000 --- a/.changeset/fix-triage-label-slug.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -'@bradygaster/squad-sdk': patch -'@bradygaster/squad-cli': patch ---- - -Fix triage label slug derivation: use `slugify()` instead of `toLowerCase()` so multi-word agent names produce valid GitHub labels (e.g. "Steve Rogers" → `squad:steve-rogers` instead of `squad:steve rogers`). - -Pre-create all `squad:{member}` labels at watch startup via `ensureTag()` so `gh issue edit --add-label` never fails on missing labels. diff --git a/.changeset/fix-watch-windows-shared-fetch.md b/.changeset/fix-watch-windows-shared-fetch.md deleted file mode 100644 index cee13e02d..000000000 --- a/.changeset/fix-watch-windows-shared-fetch.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(watch): Windows shell:true, shared agent-spawn, round-level fetch (#920, #923) - -Three fixes for the watch --execute subsystem: - -1. Added shell: IS_WINDOWS to all 37+ execFile calls so commands resolve - through PATH on Windows (fixes spawn EINVAL errors). - -2. Created shared agent-spawn.ts module replacing 7 copy-pasted - buildAgentCommand() implementations. Default changed from deprecated - gh copilot to standalone copilot CLI. - -3. Added RoundData shared fetch — issues and PRs fetched once per round - instead of per-capability, reducing API calls from ~40 to ~2 per round. diff --git a/.changeset/fleet-dispatch-hybrid.md b/.changeset/fleet-dispatch-hybrid.md deleted file mode 100644 index 70f5d8b7a..000000000 --- a/.changeset/fleet-dispatch-hybrid.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -Add /fleet hybrid dispatch mode for squad watch --execute (#775) — enables parallel issue analysis via Copilot CLI /fleet, 2.9x faster than sequential dispatch for read-heavy work diff --git a/.changeset/git-state-backends.md b/.changeset/git-state-backends.md deleted file mode 100644 index c3a4582dd..000000000 --- a/.changeset/git-state-backends.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -feat(sdk): git-notes + orphan-branch state backends for .squad/ - -Adds git-native state storage backends as alternatives to the local (disk) -approach: - -- **orphan-branch** (`squad-state`): Dedicated orphan branch with no common - ancestor. State files never appear in main. -- **two-layer** (notes + orphan): Git notes as best-effort commit annotations - plus orphan branch for durable state. Recommended for teams. - -Configure via `.squad/config.json`: `{ "stateBackend": "two-layer" }` or -the `--state-backend` CLI flag. \ No newline at end of file diff --git a/.changeset/init-upgrade-parity-tests.md b/.changeset/init-upgrade-parity-tests.md deleted file mode 100644 index 8d97181d0..000000000 --- a/.changeset/init-upgrade-parity-tests.md +++ /dev/null @@ -1,8 +0,0 @@ ---- ---- - -test: add init/upgrade/doctor parity test suite - -7 tests verifying that init and upgrade produce equivalent scaffolding. -Guards against drift where new init features (like casting) are not -mirrored in upgrade. diff --git a/.changeset/iter9-non-interactive-mcp-load.md b/.changeset/iter9-non-interactive-mcp-load.md deleted file mode 100644 index d4a0f0312..000000000 --- a/.changeset/iter9-non-interactive-mcp-load.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -iter-9: inject `--yolo --additional-mcp-config @.mcp.json` in all non-interactive copilot spawns; fix path regression from `.copilot/mcp-config.json` (iter-7) to `.mcp.json` (iter-8 canonical location); add fallback warning when `.mcp.json` is absent; add `--yolo` deduplication guard; document Copilot CLI 1.0.59+ folder-trust security gate diff --git a/.changeset/iterative-retrieval-skill.md b/.changeset/iterative-retrieval-skill.md deleted file mode 100644 index 8a1e8fc4c..000000000 --- a/.changeset/iterative-retrieval-skill.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- -feat: add iterative-retrieval skill for structured max-3-cycle agent spawning \ No newline at end of file diff --git a/.changeset/keda-scaler-docs.md b/.changeset/keda-scaler-docs.md deleted file mode 100644 index f838ef7d8..000000000 --- a/.changeset/keda-scaler-docs.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -docs: Add KEDA external scaler template for GitHub issue-driven autoscaling - -New template documenting how to use keda-copilot-scaler for scaling -agent pods to zero when idle, with rate-limit-aware polling. - -Closes #516 diff --git a/.changeset/loop-command.md b/.changeset/loop-command.md deleted file mode 100644 index 80097834d..000000000 --- a/.changeset/loop-command.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -feat(cli): Add `squad loop` command — prompt-driven continuous work loop - -New `squad loop` command reads a `loop.md` file and runs it as a continuous work loop. -No GitHub issues required — the prompt is the work driver. Includes `--init` to scaffold -a boilerplate loop file, frontmatter validation, and composable capability flags. diff --git a/.changeset/machine-capability-routing.md b/.changeset/machine-capability-routing.md deleted file mode 100644 index 2ac99caf7..000000000 --- a/.changeset/machine-capability-routing.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -feat: Machine capability discovery and `needs:*` label-based issue routing - -Added capability filtering to Ralph's watch command. Issues with `needs:*` labels -(e.g., `needs:gpu`, `needs:browser`) are only processed by Ralph instances whose -machine has those capabilities declared in `machine-capabilities.json`. - -This enables multi-machine Squad deployments where different machines handle -different types of work based on their available tooling. - -Closes #514 \ No newline at end of file diff --git a/.changeset/manifest-driven-skills.md b/.changeset/manifest-driven-skills.md deleted file mode 100644 index 9caad36df..000000000 --- a/.changeset/manifest-driven-skills.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch -"@bradygaster/squad-cli": patch ---- - -fix: use TEMPLATE_MANIFEST to drive skill installation instead of wholesale directory copy - -Both sdkInitSquad() and syncAllSkills() previously copied the entire templates/skills/ -directory, ignoring the curated 8-skill subset declared in TEMPLATE_MANIFEST. -This meant all 37+ template skills shipped on every init/upgrade, and -overwriteOnUpgrade was never consulted. - -Now both code paths iterate TEMPLATE_MANIFEST entries: -- init (SDK): only the 8 manifest skills are copied on first init -- upgrade (CLI): syncAllSkills() reads manifest entries, respects overwriteOnUpgrade - -Fixes #833 diff --git a/.changeset/mcp-frontmatter-init.md b/.changeset/mcp-frontmatter-init.md deleted file mode 100644 index 9ef59b152..000000000 --- a/.changeset/mcp-frontmatter-init.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- - -Add `squad init --mcp-frontmatter` to write MCP server config into the Squad agent frontmatter instead of `.copilot/mcp-config.json` for compatible agent harnesses. diff --git a/.changeset/memory-diagnostics-config.md b/.changeset/memory-diagnostics-config.md deleted file mode 100644 index e4518f5a1..000000000 --- a/.changeset/memory-diagnostics-config.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -Allow memory diagnostics log level to be configured from `.squad/config.json`. diff --git a/.changeset/notification-routing-skill.md b/.changeset/notification-routing-skill.md deleted file mode 100644 index 7f71556f3..000000000 --- a/.changeset/notification-routing-skill.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- - -feat: add notification-routing skill for pub-sub channel routing \ No newline at end of file diff --git a/.changeset/perf-charter-discovery-parallel.md b/.changeset/perf-charter-discovery-parallel.md deleted file mode 100644 index c27ce2c7d..000000000 --- a/.changeset/perf-charter-discovery-parallel.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch ---- - -perf(agents): parallelize charter discovery with concurrency limit to reduce multi-agent load time diff --git a/.changeset/perf-resolution-memoize.md b/.changeset/perf-resolution-memoize.md deleted file mode 100644 index 25cf049b6..000000000 --- a/.changeset/perf-resolution-memoize.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch -"@bradygaster/squad-cli": patch ---- - -perf(resolution): memoize squad-dir lookups; deduplicate squads.json reads to reduce filesystem I/O on repeated resolution calls diff --git a/.changeset/perf-scheduler-async-exec.md b/.changeset/perf-scheduler-async-exec.md deleted file mode 100644 index a6065f277..000000000 --- a/.changeset/perf-scheduler-async-exec.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch ---- - -perf(scheduler): convert sequential async execution to concurrent with bounded concurrency to improve multi-agent dispatch throughput diff --git a/.changeset/persistent-ralph.md b/.changeset/persistent-ralph.md deleted file mode 100644 index 35d94bbd8..000000000 --- a/.changeset/persistent-ralph.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@bradygaster/squad-sdk': minor -'@bradygaster/squad-cli': minor ---- - -Enable persistent Ralph — heartbeat cron + healthCheck timer - -- Enable cron schedule in squad-heartbeat.yml (all 5 sync locations) -- Enable RalphMonitor healthCheck timer (previously commented out pre-migration) -- Add platform detection tests for getRalphScanCommands (GitHub/ADO/Planner) -- Add healthCheck timer tests with fake timers (start/stop/interval/stale detection) diff --git a/.changeset/plugin-extensibility-context.md b/.changeset/plugin-extensibility-context.md deleted file mode 100644 index 4813586f7..000000000 --- a/.changeset/plugin-extensibility-context.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-cli": patch -"@bradygaster/squad-sdk": patch ---- - -feat: add declarative plugin behavior context proof - -Adds static plugin metadata, lifecycle state, runtime context injection, -declarative provider contracts, and behavior simulations for Graphify, -MemPalace, and Index Server plugin samples. Enabled plugins can now contribute -installed static guidance and typed memory/knowledge provider summaries to -spawned-agent prompts while preserving the no-execution security boundary. diff --git a/.changeset/quiet-notifications.md b/.changeset/quiet-notifications.md deleted file mode 100644 index 5a8880512..000000000 --- a/.changeset/quiet-notifications.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -Add `--notify-level` to control watch round reporting noise (#803) - -- `--notify-level important` (default): only print rounds with actual work items -- `--notify-level all`: print every round including empty (old behavior) -- `--notify-level none`: suppress all round output -- Add machine name (`os.hostname()`) and repo name to round headers for attribution - (shown in round headers when the board has items, and in "Board is clear" message) -- Configurable via `.squad/config.json` watch section: `"notifyLevel": "important"` -- Empty rounds silenced by default — no more "Round 160, Round 161" spam diff --git a/.changeset/rai-built-in-agent.md b/.changeset/rai-built-in-agent.md deleted file mode 100644 index 6e3e8894a..000000000 --- a/.changeset/rai-built-in-agent.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -'@bradygaster/squad-cli': minor -'@bradygaster/squad-sdk': minor ---- - -Add Rai as Squad's third built-in agent — a Responsible AI (RAI) reviewer - -- Rai is always on the roster (like Scribe and Ralph), exempt from casting -- Traffic light verdict model: 🟢 Green (proceed), 🟡 Yellow (advisory), 🔴 Red (blocking) -- Background mode by default — only blocks on critical RAI violations -- Phase 1 high-signal checks: credentials, injection, harmful content, bias, PII -- New templates: Rai-charter.md, rai-policy.md -- New `.squad/rai/` directory with policy.md and audit-trail.md -- Tiered opt-out model (cannot disable critical checks) diff --git a/.changeset/ralph-two-pass-scan-skill.md b/.changeset/ralph-two-pass-scan-skill.md deleted file mode 100644 index 35a7ff21d..000000000 --- a/.changeset/ralph-two-pass-scan-skill.md +++ /dev/null @@ -1,4 +0,0 @@ ---- ---- - -Add ralph-two-pass-scan skill — lightweight issue list scan before selective hydration, cutting Ralph's GitHub API calls by ~72% per round (resolves #596) diff --git a/.changeset/readiness-file-list.md b/.changeset/readiness-file-list.md deleted file mode 100644 index 5cc36c951..000000000 --- a/.changeset/readiness-file-list.md +++ /dev/null @@ -1,7 +0,0 @@ ---- ---- - -ci: add file list with line stats to PR readiness comment - -The PR readiness bot now shows changed files with per-file addition/deletion -counts, scope classification (Product/Infrastructure/Mixed), and totals. diff --git a/.changeset/readiness-rerun.md b/.changeset/readiness-rerun.md deleted file mode 100644 index f1f2ee952..000000000 --- a/.changeset/readiness-rerun.md +++ /dev/null @@ -1,8 +0,0 @@ ---- ---- - -ci: re-run PR readiness check after Squad CI completes - -Added workflow_run trigger to the readiness check so it refreshes after -CI finishes. Uses PR API for draft status instead of env var (more reliable -for workflow_run events). Includes 3 new draft-override tests. diff --git a/.changeset/reflect-skill.md b/.changeset/reflect-skill.md deleted file mode 100644 index 1263013b1..000000000 --- a/.changeset/reflect-skill.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- -feat: add reflect skill for in-session learning capture and mistake prevention \ No newline at end of file diff --git a/.changeset/repo-import-export.md b/.changeset/repo-import-export.md deleted file mode 100644 index f6127f02d..000000000 --- a/.changeset/repo-import-export.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -'@bradygaster/squad-cli': minor -'@bradygaster/squad-sdk': minor ---- - -Add `--repo` and `--branch` flags to `squad export` and `squad import` commands, enabling users to push/pull Squad configuration directly to/from a GitHub repository via the GitHub Contents API. diff --git a/.changeset/retro-enforcement.md b/.changeset/retro-enforcement.md deleted file mode 100644 index 1cc4d4ee3..000000000 --- a/.changeset/retro-enforcement.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": patch ---- - -Add retro enforcement skill with Test-RetroOverdue and ceremonies template update. - -- New skill: retro-enforcement - coordinator integration pattern for automated retro cadence enforcement -- Action items tracked as GitHub Issues (not markdown checklists) -- Production data: 0% to 100% completion rate after switching formats -- Test-RetroOverdue PowerShell function detects overdue retros and blocks work queue -- Ceremonies template updated with enforcement-aware retrospective definition diff --git a/.changeset/scope-boundary-check.md b/.changeset/scope-boundary-check.md deleted file mode 100644 index 6f98a8bd3..000000000 --- a/.changeset/scope-boundary-check.md +++ /dev/null @@ -1,8 +0,0 @@ ---- ---- - -ci: scope boundary enforcement for repo-health PRs - -New CI check that fails repo-health PRs if they modify product source -code under packages/*/src/. Enforces separation between infrastructure -and product changes. diff --git a/.changeset/scratch-dir-utility.md b/.changeset/scratch-dir-utility.md deleted file mode 100644 index 9fd5d5769..000000000 --- a/.changeset/scratch-dir-utility.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor ---- - -Add `.squad/.scratch/` directory for organized temp file management (#790) - -- `scratchDir()` — resolve and optionally create the scratch directory -- `scratchFile()` — create named temp files inside `.scratch/` -- Init scaffolds `.squad/.scratch/` and adds it to `.gitignore` -- Agents and CLI should use these utilities instead of writing temp files to repo root diff --git a/.changeset/sdk-parity-batch2-tests.md b/.changeset/sdk-parity-batch2-tests.md deleted file mode 100644 index 5a06207d4..000000000 --- a/.changeset/sdk-parity-batch2-tests.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch ---- - -Add SDK feature parity batch 2 — 64 tests covering manual ceremonies (#27), ceremony cooldown (#28), human team members (#36), constraint budget enforcement (#49 — rate limiter, file-write guards, shell restrictions, PII scrubbing), multi-agent artifact coordination (#50), and builder validation edge cases. diff --git a/.changeset/sdk-parity-batch3-tests.md b/.changeset/sdk-parity-batch3-tests.md deleted file mode 100644 index 79aa07c39..000000000 --- a/.changeset/sdk-parity-batch3-tests.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch ---- - -test: SDK feature parity batch 3 — 46 tests for #31, #47, #45, #46 - -Adds 46 automated tests covering 4 SDK features from the #341 parity matrix: -- RalphMonitor idle-watch mode (#31): construction, event handling, stale session detection -- Platform detection (#47): GitHub/Azure DevOps URL parsing, detectPlatformFromUrl -- Reviewer lockout (#45): rejection protocol, per-artifact scope, persistence -- Deadlock handling (#46): all-agents-locked detection, clearLockout escalation, recovery diff --git a/.changeset/self-upgrade.md b/.changeset/self-upgrade.md deleted file mode 100644 index 0567983d1..000000000 --- a/.changeset/self-upgrade.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -Add `squad upgrade --self` to upgrade the CLI package itself (#798) - -- `squad upgrade --self` → installs `@bradygaster/squad-cli@latest` (stable) -- `squad upgrade --self --insider` → installs `@bradygaster/squad-cli@insider` (prerelease) -- After self-upgrade, automatically continues with repo upgrade to apply new templates -- Detects package manager (npm/pnpm/yarn) from npm_config_user_agent -- Clear error on permission denied (suggests sudo or npx) -- Help text updated with new flags diff --git a/.changeset/session-init-version-check.md b/.changeset/session-init-version-check.md deleted file mode 100644 index 8c87310e0..000000000 --- a/.changeset/session-init-version-check.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -feat: session init update check with extensible session-init reference - -Adds a Session Init block to squad.agent.md that runs Step 1 (Update Check) -at session start. When a newer @bradygaster/squad-cli version exists for the -user's channel (latest/insider/preview), appends a notice to the greeting. -Respects SQUAD_NO_UPDATE_CHECK=1 kill switch. - -Adds `.squad-templates/session-init-reference.md` with the full update-check -procedure (channel detection, hybrid cache strategy, greeting format) and -registers it in TEMPLATE_MANIFEST so `squad upgrade` keeps it current. - -Also adds squad-version-check SKILL.md to .copilot/skills with internals -knowledge about version stamping and the npm registry probe mechanism. - -Also fixes pre-existing CI failures: adds Commit step to scribe-charter.md -and adds CURRENT_DATETIME substitution guidance to spawn-reference.md. diff --git a/.changeset/skill-discovery-paths.md b/.changeset/skill-discovery-paths.md deleted file mode 100644 index d5522bef1..000000000 --- a/.changeset/skill-discovery-paths.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- - -Squad coordinator now scans all 5 project skill directories: Copilot CLI's 3 -official project paths — `.github/skills/`, `.claude/skills/`, `.agents/skills/` -(per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills) -— plus Squad's existing conventions `.squad/skills/` and `.copilot/skills/`. -Precedence: `.squad/skills/` > `.copilot/skills/` > `.github/skills/` > -`.claude/skills/` > `.agents/skills/` (dedup by directory name). Personal -paths (`~/.copilot/skills/`, `~/.agents/skills/`) are deliberately excluded -from explicit routing — Copilot CLI injects them ambiently. This closes a gap -where skills placed in `.github/skills/` (a common location alongside other -`.github/` tooling) were loaded by Copilot CLI but invisible to Squad's -coordinator-attached skill-aware routing. diff --git a/.changeset/smart-pr-nudge.md b/.changeset/smart-pr-nudge.md deleted file mode 100644 index 2144528df..000000000 --- a/.changeset/smart-pr-nudge.md +++ /dev/null @@ -1,8 +0,0 @@ ---- ---- - -ci: add smart PR nudge for stale PRs - -New workflow that runs on weekdays and posts actionable diagnoses on PRs -stale for 7+ days. Checks CI status, unresolved threads, missing reviews, -outdated branches, and draft status. Won't nudge the same PR twice per week. diff --git a/.changeset/squad-commands-review-fixes.md b/.changeset/squad-commands-review-fixes.md deleted file mode 100644 index b46fb7878..000000000 --- a/.changeset/squad-commands-review-fixes.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -'@bradygaster/squad': patch -'@bradygaster/squad-sdk': patch ---- - -Fix squad-commands skill routing and configuration for Copilot integration - -- **templates.ts**: Correct destination path for squad-commands SKILL.md from `skills/squad-commands/SKILL.md` to `../.copilot/skills/squad-commands/SKILL.md` to match other built-in skills -- **init.ts**: Add `'squad-commands'` to MANIFEST_SKILL_NAMES array to include the skill in project initialization -- **squad-commands SKILL.md**: Convert triggers from YAML list to inline array format and remove generic triggers ("help", "how do I") that conflict with other skills; retain: "squad commands", "what can squad do", "show me squad options", "slash commands" -- **Template sync**: Regenerate all mirrors via sync-templates.mjs to propagate routing updates to .copilot and .squad templates diff --git a/.changeset/squad-commands-skill.md b/.changeset/squad-commands-skill.md deleted file mode 100644 index 9fea5bce3..000000000 --- a/.changeset/squad-commands-skill.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -feat: add squad-commands skill for in-chat command discovery - -Adds a categorized menu skill (`skills/squad-commands/SKILL.md`) that the -coordinator reads when the user asks "squad commands", "help", or "what can -squad do". Also adds a routing row and greeting tip in squad.agent.md, and -registers the template in TEMPLATE_MANIFEST with overwriteOnUpgrade=true. - -Also fixes pre-existing CI failures: adds Commit step to scribe-charter.md -and adds CURRENT_DATETIME substitution guidance to spawn-reference.md. diff --git a/.changeset/squad-home-presets.md b/.changeset/squad-home-presets.md deleted file mode 100644 index 5ee44fea8..000000000 --- a/.changeset/squad-home-presets.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -feat: add SQUAD_HOME env var and preset system - -- Add `SQUAD_HOME` environment variable support for a roaming squad root directory -- Add preset system for reusable agent configurations (list, show, apply, init) -- Ship a default built-in preset with 5 agents (lead, reviewer, devrel, security, docs) -- Add `squad preset` CLI command with list, show, apply, and init subcommands -- Resolves #1038 diff --git a/.changeset/squad-scheduler.md b/.changeset/squad-scheduler.md deleted file mode 100644 index c008a8920..000000000 --- a/.changeset/squad-scheduler.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor -"@bradygaster/squad-cli": minor ---- - -Generic, provider-agnostic scheduler for Squad (#296) — unified schedule.json manifest with LocalPolling and GitHubActions provider adapters, CLI commands (list, run, init, status), schema validation, and cron/interval trigger evaluation. diff --git a/.changeset/squash-the-gremlins-cli.md b/.changeset/squash-the-gremlins-cli.md deleted file mode 100644 index e4314c1b6..000000000 --- a/.changeset/squash-the-gremlins-cli.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Fix Windows spawn EINVAL in watch capabilities by adding `shell: true` to `execFile()` calls in monitor-teams, monitor-email, retro, and decision-hygiene capabilities. Add Copilot CLI preflight check to `squad doctor` and monitor capabilities so missing `gh copilot` extension is flagged early. Improve team hire confirmation UX to show member names inline with the prompt. (closes #920, closes #880, closes #1107) diff --git a/.changeset/squash-the-gremlins-sdk.md b/.changeset/squash-the-gremlins-sdk.md deleted file mode 100644 index 1c06122bc..000000000 --- a/.changeset/squash-the-gremlins-sdk.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-sdk': patch ---- - -Bump `@github/copilot-sdk` from `^0.1.32` to `^0.3.0` to fix ESM module resolution error (ERR_MODULE_NOT_FOUND for vscode-jsonrpc/node). Add explicit GitHub repo config support in `.squad/config.json` (`{ "github": { "owner": "...", "repo": "..." } }`) so platform adapter prefers user-specified repo over auto-detection from origin remote. (closes #1062, closes #905) diff --git a/.changeset/state-backend-global.md b/.changeset/state-backend-global.md deleted file mode 100644 index 61906e8bf..000000000 --- a/.changeset/state-backend-global.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -'@bradygaster/squad-sdk': minor -'@bradygaster/squad-cli': patch ---- - -Add delete() and append() to StateBackend interface; add resolveSquadState() entry point; add StateBackendStorageAdapter; add git-notes agent protocol templates - -- Add `delete()` and `append()` methods to the `StateBackend` interface -- Implement delete/append for all three backends (local, orphan, two-layer) -- Fix orphan backend append to preserve trailing whitespace via readUntrimmed() -- Add `SquadStateContext` interface and `resolveSquadState()` factory in resolution module -- Add `StateBackendStorageAdapter` — bridges StateBackend as a StorageProvider so SDK modules that accept `storage: StorageProvider` work with git-notes and orphan backends -- Add `storage` field to `SquadStateContext` — local uses FSStorageProvider directly, orphan/two-layer use the adapter -- Export `StateBackendStorageAdapter` from SDK public API -- Wire `resolveSquadState()` into CLI entry so the state backend is resolved once at startup -- Pass pre-resolved `stateContext` through to watch config to avoid redundant resolution -- Add `notes-protocol.md` template — agent contract for git-notes state (namespaces, JSON schema, fetch/push, conflict handling) -- Add `scripts/notes/fetch.ps1` template — fetch notes + one-time refspec setup + merge after conflict -- Add `scripts/notes/write-note.ps1` template — agent helper for writing notes with JSON validation and push retry -- Update state-backends docs with "Using with Copilot CLI Sessions" section (copilot-instructions snippet, promotion flow, template index) -- This is the SDK foundation for making state backends squad-wide (Phase 1) diff --git a/.changeset/state-backend-hardening.md b/.changeset/state-backend-hardening.md deleted file mode 100644 index f28e1dd13..000000000 --- a/.changeset/state-backend-hardening.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'@bradygaster/squad-sdk': patch ---- - -State backend hardening: retry with exponential backoff for transient git errors, circuit-breaker to prevent cascading failures, read-only startup verification, and observable error surfacing replacing silent swallowing. diff --git a/.changeset/state-tools-hardening.md b/.changeset/state-tools-hardening.md deleted file mode 100644 index 41a9317e5..000000000 --- a/.changeset/state-tools-hardening.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-sdk": patch -"@bradygaster/squad-cli": patch ---- - -Harden runtime state tools so write, append, and delete only mutate approved Squad runtime state paths, and refresh prompt templates to require state-tool persistence and literal datetime propagation. diff --git a/.changeset/subprocess-integration-tests.md b/.changeset/subprocess-integration-tests.md deleted file mode 100644 index 9535f967c..000000000 --- a/.changeset/subprocess-integration-tests.md +++ /dev/null @@ -1,8 +0,0 @@ ---- ---- - -test: add Copilot CLI subprocess integration tests for SQUAD_TEAM_ROOT - -8 tests covering SQUAD_TEAM_ROOT env-var resolution, fallback to cwd, -and resolveSquad() integration. Guards against subprocess working directory -bugs in Copilot CLI bang commands. diff --git a/.changeset/teams-comms-adapter.md b/.changeset/teams-comms-adapter.md deleted file mode 100644 index c676b9dd9..000000000 --- a/.changeset/teams-comms-adapter.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"@bradygaster/squad-sdk": minor ---- - -feat(sdk): Add Microsoft Teams communication adapter - -BREAKING: `createCommunicationAdapter` is now async (returns `Promise`). -Callers must await the result. - -New Teams adapter for bidirectional chat via Microsoft Graph API. -Supports browser auth (PKCE), device code flow, token caching, -1:1 chat and channel messaging. diff --git a/.changeset/tiered-memory.md b/.changeset/tiered-memory.md deleted file mode 100644 index f2d2336b2..000000000 --- a/.changeset/tiered-memory.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor -"@bradygaster/squad-sdk": minor ---- -feat: add tiered-memory skill for hot/cold/wiki agent context management \ No newline at end of file diff --git a/.changeset/watch-circuit-breaker.md b/.changeset/watch-circuit-breaker.md deleted file mode 100644 index b9b335267..000000000 --- a/.changeset/watch-circuit-breaker.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -feat(watch): circuit breaker integration for rate limit protection (#515) - -Adds GitHub API rate limit protection to Ralph's watch command via -the Predictive Circuit Breaker from PR #518. - -**What changed (additive patch — existing flow untouched):** -- `gh-cli.ts`: Added `ghRateLimitCheck()` and `isRateLimitError()` helpers -- `watch.ts`: Added `CircuitBreakerState` type + persistence helpers -- `watch.ts`: Added `executeRound()` wrapper that gates the existing - `runCheck()` call through pre-flight quota checks -- `watch.ts`: Added `roundInProgress` flag to prevent overlapping rounds - -**Circuit breaker state machine:** -- CLOSED → OPEN: When traffic light is red or predictor says exhaustion imminent -- OPEN → HALF-OPEN: After cooldown expires (exponential: 2m → 4m → 8m → ... → 30m cap) -- HALF-OPEN → CLOSED: After 2 consecutive successful rounds -- HALF-OPEN → OPEN: On rate limit error during probe - -State persists to `.squad/ralph-circuit-breaker.json` across restarts. - -**Tests:** 16 new tests covering state transitions, race condition guard, -predictive integration, and `isRateLimitError` detection. diff --git a/.changeset/watch-health.md b/.changeset/watch-health.md deleted file mode 100644 index 7ea8999a3..000000000 --- a/.changeset/watch-health.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -feat(watch): health check — show running watch instance status (#808) - -Adds `squad watch --health` to display the status of a running watch -instance: PID, uptime, auth account, capabilities, and auth drift -detection. Writes `.squad/.watch-pid.json` at startup for instance -tracking. Detects and cleans up stale PID files from crashed instances. diff --git a/.changeset/watch-ux-fixes-2141.md b/.changeset/watch-ux-fixes-2141.md deleted file mode 100644 index 961772e8f..000000000 --- a/.changeset/watch-ux-fixes-2141.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": patch ---- - -fix(watch): 3 UX improvements — round timing output, --log-file tee flag, immediate startup feedback (#2141) \ No newline at end of file diff --git a/.changeset/watch-verbose-mode.md b/.changeset/watch-verbose-mode.md deleted file mode 100644 index 3dc92ae8d..000000000 --- a/.changeset/watch-verbose-mode.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@bradygaster/squad-cli": minor ---- - -Add --verbose flag to squad watch for debugging empty boards and silent failures (#781) diff --git a/.changeset/widen-changelog-gate-template-paths.md b/.changeset/widen-changelog-gate-template-paths.md deleted file mode 100644 index 31563a7e3..000000000 --- a/.changeset/widen-changelog-gate-template-paths.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -'@bradygaster/squad-cli': patch ---- - -Widen changelog-gate coverage for template and scaffolding paths - -Previously, the changelog gate only required a changeset for `packages/squad-(sdk|cli)/src/` changes, so template and scaffolding updates under `packages/squad-(sdk|cli)/templates/`, `.squad-templates/`, top-level `templates/`, and agent charters under `.squad/agents/*/charter.md` could reach users with no release-note entry. This widens the gate to those paths so user-facing template and scaffolding changes are no longer silently omitted from release notes. Closes #1156. diff --git a/.changeset/windows-ado-fixes.md b/.changeset/windows-ado-fixes.md deleted file mode 100644 index 3212cbdb5..000000000 --- a/.changeset/windows-ado-fixes.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-cli": patch -"@bradygaster/squad-sdk": patch ---- - -Fix Windows Azure CLI execution and ADO state mapping in squad watch diff --git a/.changeset/wire-squad-route.md b/.changeset/wire-squad-route.md deleted file mode 100644 index 574c059fa..000000000 --- a/.changeset/wire-squad-route.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -'@bradygaster/squad-sdk': minor ---- - -fix(sdk): wire `squad_route` tool handler to actually create target sessions - -The `squad_route` tool is documented in `packages/squad-sdk/README.md`, -`docs/src/content/docs/reference/sdk.md`, -`docs/src/content/docs/reference/api-reference.md`, and the -`build-autonomous-agent` guide as routing tasks and creating new sessions -for the target agent. The previous implementation returned -`resultType: 'success'` with the hard-coded text "Session creation will be -implemented when session lifecycle is in place" without ever spawning a -session. SDK embedders following the documented usage -(`toolRegistry.getTool('squad_route').handler({ ... })`) received a -confident "Task routed to X" success payload while no agent ever started — -a silent no-op masquerading as success. - -This change: - -- Adds an optional 5th positional `fanOutDepsGetter` constructor parameter - to `ToolRegistry`. Existing 4-arg constructions are unaffected. -- When `fanOutDepsGetter` returns dependencies, `squad_route` calls - `spawnParallel` with a single config (charter compile → model resolve → - `createSession` → initial message), matching the SDK `Coordinator` - fan-out path. -- When `fanOutDepsGetter` is absent or returns `undefined`, the handler - returns `resultType: 'failure'` with `error: 'fan-out-deps-unavailable'` - and remediation guidance, replacing the previous false-success. -- Normalizes `targetAgent` to lowercase (matching charter-loading convention). -- Distinguishes roster "not found" errors from infrastructure I/O failures. -- Updates `docs/src/content/docs/guide/build-autonomous-agent.md` with a - note about the `fanOutDepsGetter` requirement and `fan-out-deps-unavailable` - failure mode. - -Behavior change for embedders that relied on the stub's unconditional -success: those calls now return an honest failure. Remediation is to -either (a) construct `ToolRegistry` with a `fanOutDepsGetter`, or -(b) intercept `squad_route` via `SquadSessionHooks.onPreToolUse`. - -Related: #1029 (named-agent delegation answering inline) — different code -path (Copilot CLI `task` tool / coordinator prompt), not closed by this PR, -but shares the same root-cause family of silent-no-op delegation primitives. diff --git a/CHANGELOG.md b/CHANGELOG.md index ebd0b5e07..dbb2fbc6a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,36 +4,109 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +## [0.10.0] — 2026-06-07 + +First stable release since v0.9.4 (April 25). Consumes 97 changesets (sdk: 50, cli: 71). + +### Security +- (cli) iter-9: inject `--yolo --additional-mcp-config @.mcp.json` in all non-interactive copilot spawns; fix path regression from `.copilot/mcp-config.json` (iter-7) to `.mcp.json` (iter-8 canonical location); add fallback warning when `.mcp.json` is absent; add `--yolo` deduplication guard; document Copilot CLI 1.0.59+ folder-trust security gate + +### Performance +- (cli) Add /fleet hybrid dispatch mode for squad watch --execute (#775) — enables parallel issue analysis via Copilot CLI /fleet, 2.9x faster than sequential dispatch for read-heavy work +- (sdk) perf(agents): parallelize charter discovery with concurrency limit to reduce multi-agent load time +- (sdk+cli) perf(resolution): memoize squad-dir lookups; deduplicate squads.json reads to reduce filesystem I/O on repeated resolution calls +- (sdk) perf(scheduler): convert sequential async execution to concurrent with bounded concurrency to improve multi-agent dispatch throughput + +### Added +- (sdk) Add rework rate OTEL metrics (#265) — tracks PR revision patterns as the emerging 5th DORA metric +- (sdk+cli) Add routing.md to squad export/import functionality +- (sdk) Add SkillScriptLoader, handler types, and applySkillHandlers for executable skill handler scripts +- (cli) feat: APM integration — squad skill publish/install + apm.yml in init +- (sdk) feat: Cooperative rate limiting with predictive circuit breaker +- (sdk+cli) Cross-squad orchestration — discovery, delegation, and manifest (#316). Adds manifest schema, `squad discover` / `squad delegate` commands, and runtime module for coordinating work across multiple Squad instances. +- (cli) Add deprecation warnings for tunnel, rc, and REPL commands. The interactive shell (no-args), `squad start`, `squad start --tunnel`, `squad rc`, and `squad rc-tunnel` now emit yellow deprecation notices pointing users to the GitHub Copilot CLI. No behavior changes — all commands still work. +- (cli) docs: add fork contribution workflow to CONTRIBUTING.md +- (cli) Add user-facing documentation for state backends (local, orphan-branch, two-layer) +- (sdk) Add dual-mode deployment support for capabilities routing. +- (sdk+cli) feat: add error-recovery skill for standard agent failure recovery patterns +- (sdk+cli) Add external state storage — move .squad/ out of the working tree (#792) +- (sdk+cli) Add fact-checker as a built-in agent role (#789) +- (cli) Fix squad doctor and upgrade for insiders installs: add .squad/casting/ to ENSURE_DIRECTORIES, scaffold casting defaults from templates with permission-safe fallback, and clarify ESM warnings for global installs. +- (sdk) Sync squad.agent.md roster when agents added to team.md +- (cli) fix(ci): fix multiple CI test failures introduced by PR #1035 coordinator slimming +- (sdk+cli) Warn when squad.agent.md template is missing during upgrade or init instead of silently skipping file creation. Adds `warnings` field to `InitResult` for structured error reporting. +- (sdk+cli) feat(sdk): git-notes + orphan-branch state backends for .squad/ +- (sdk+cli) feat: add iterative-retrieval skill for structured max-3-cycle agent spawning +- (cli) docs: Add KEDA external scaler template for GitHub issue-driven autoscaling +- (cli) feat(cli): Add `squad loop` command — prompt-driven continuous work loop +- (sdk+cli) feat: Machine capability discovery and `needs:*` label-based issue routing +- (sdk+cli) Add `squad init --mcp-frontmatter` to write MCP server config into the Squad agent frontmatter instead of `.copilot/mcp-config.json` for compatible agent harnesses. +- (sdk+cli) feat: add notification-routing skill for pub-sub channel routing +- (sdk+cli) feat: add declarative plugin behavior context proof +- (cli) Add `--notify-level` to control watch round reporting noise (#803) +- (sdk+cli) Add Rai as Squad's third built-in agent — a Responsible AI (RAI) reviewer +- (sdk+cli) feat: add reflect skill for in-session learning capture and mistake prevention +- (sdk+cli) Add `--repo` and `--branch` flags to `squad export` and `squad import` commands, enabling users to push/pull Squad configuration directly to/from a GitHub repository via the GitHub Contents API. +- (sdk+cli) Add retro enforcement skill with Test-RetroOverdue and ceremonies template update. +- (sdk) Add `.squad/.scratch/` directory for organized temp file management (#790) +- (sdk) Add SDK feature parity batch 2 — 64 tests covering manual ceremonies (#27), ceremony cooldown (#28), human team members (#36), constraint budget enforcement (#49 — rate limiter, file-write guards, shell restrictions, PII scrubbing), multi-agent artifact coordination (#50), and builder validation edge cases. +- (sdk) test: SDK feature parity batch 3 — 46 tests for #31, #47, #45, #46 +- (cli) Add `squad upgrade --self` to upgrade the CLI package itself (#798) +- (cli) feat: session init update check with extensible session-init reference +- (cli) feat: add squad-commands skill for in-chat command discovery +- (sdk+cli) feat: add SQUAD_HOME env var and preset system +- (cli) Fix Windows spawn EINVAL in watch capabilities by adding `shell: true` to `execFile()` calls in monitor-teams, monitor-email, retro, and decision-hygiene capabilities. Add Copilot CLI preflight check to `squad doctor` and monitor capabilities so missing `gh copilot` extension is flagged early. Improve team hire confirmation UX to show member names inline with the prompt. (closes #920, closes #880, closes #1107) +- (sdk) Bump `@github/copilot-sdk` from `^0.1.32` to `^0.3.0` to fix ESM module resolution error (ERR_MODULE_NOT_FOUND for vscode-jsonrpc/node). Add explicit GitHub repo config support in `.squad/config.json` (`{ "github": { "owner": "...", "repo": "..." } }`) so platform adapter prefers user-specified repo over auto-detection from origin remote. (closes #1062, closes #905) +- (sdk+cli) Add delete() and append() to StateBackend interface; add resolveSquadState() entry point; add StateBackendStorageAdapter; add git-notes agent protocol templates +- (sdk) feat(sdk): Add Microsoft Teams communication adapter +- (sdk+cli) feat: add tiered-memory skill for hot/cold/wiki agent context management +- (cli) feat(watch): circuit breaker integration for rate limit protection (#515) +- (cli) feat(watch): health check — show running watch instance status (#808) +- (cli) Add --verbose flag to squad watch for debugging empty boards and silent failures (#781) + ### Fixed -- `squad init` no longer runs `git init` automatically when initialized inside a monorepo subdirectory (#939). It now shows a warning and suggests running from the git root instead. -- Azure DevOps adapter (`az` CLI calls) now use `shell: true` on Windows so `.cmd` wrapper scripts resolve correctly (#941). -- **Nap archival budget** (#123) — account for separator newlines in decision archival budget calculation - -### Added — Full Work Monitor for squad watch (#708) -- `--execute` flag spawns Copilot sessions to work on actionable issues autonomously -- Multi-platform support — auto-detects GitHub vs Azure DevOps from git remote URL -- Azure DevOps support: uses SDK PlatformAdapter for work items, tags, and PRs -- `--monitor-teams` / `--monitor-email` scan Teams/email for actionable items via WorkIQ -- `--board` enables project board lifecycle (In Progress → Done/Blocked + reconciliation) -- `--two-pass` lightweight scan then hydrate only actionable issues (saves API quota) -- `--wave-dispatch` parallel sub-task execution within issues (dependency-aware) -- `--retro` enforces retrospective checks (Fridays or when missed >7 days) -- `--decision-hygiene` auto-merges decision inbox when >5 files -- `--max-concurrent N` controls parallel issue execution (default: 1) -- `--timeout N` sets per-issue execution timeout in minutes (default: 30) -- `--copilot-flags "..."` passes extra flags to Copilot CLI sessions -- SubSquad discovery: automatically detects `.squad/subsquads/` for routing -- All features disabled by default — existing `squad watch` behavior unchanged - -### Added — StorageProvider Abstraction Layer -- **StorageProvider interface** (#640) — pluggable I/O contract decoupling the runtime from `node:fs` -- **FSStorageProvider** (#640) — Node.js `fs` wrapper, default provider for CLI and local workflows -- **InMemoryStorageProvider** (#640) — Map-backed, test-friendly provider for deterministic unit tests -- **SQLiteStorageProvider** (#640) — portable single-file provider using WASM-based sql.js -- **StorageError** (#640) — typed error handling with `operation` and `code` fields for structured diagnostics -- **24-method async + sync API** (#640) — full file-system surface (read, write, list, mkdir, stat, etc.); sync variants deprecated, Wave 2 removal -- **Contract test suite** (#640) — provider conformance tests ensuring all implementations satisfy the StorageProvider interface -- **Sample projects** (#640) — `storage-provider-azure` and `storage-provider-sqlite` in `samples/` +- (sdk+cli) Fix hardcoded "Brady" in template files — LLMs now use actual git username instead of example name (closes #977) +- (cli) Fix changelog-gate CI to accept .changeset/ files as alternative to direct CHANGELOG.md edits +- (sdk+cli) fix: bump CLI version to 0.9.7-preview; align E2E skill and policy gate with CONTRIBUTING.md +- (sdk+cli) fix: context overflow sentinel and coordinator size reduction (retroactive for #1035) +- (sdk+cli) Fix coordinator and Scribe templates so spawned agents receive and write the resolved current datetime instead of placeholder text. +- (cli) fix(cli): revert detect-squad-dir to zero-dependency bootstrap +- (cli) fix: restore CI green on dev — 25 regression fixes + 6 test corrections +- (cli) Fix export/import producing blank decisions.md and team.md files. Export now includes these files in the manifest, and import restores their content. +- (cli) Fix runtime commands to correctly resolve externalized state paths +- (sdk+cli) Fix 5 bugs: dotted repo names, icon spacing, board owner, charter passing, missing playbooks +- (cli) fix: `/init` with no args now accepts follow-up message as cast prompt, and `createTeam` correctly creates `team.md`/`routing.md` in fresh projects +- (cli) fix(nap): account for separator newlines in decision archival budget +- (cli) fix(cli): wire --team-root / SQUAD_TEAM_ROOT into squad resolution for nap, status, and cost commands (#734) +- (cli) fix: CLI no longer bails when configured is false; starts onboarding session instead (#843) +- (cli) fix(coordinator): resolve externalized state, teamRoot, stale work, and cleanup loops +- (sdk+cli) Fix permission handler to use `approve-once` instead of deprecated `approved` kind, aligning with Copilot CLI v1.0.54+ permission contract +- (cli) Fix post-init message to recommend `copilot --agent squad` instead of deprecated `squad` command (closes #1034, closes #1007) +- (sdk+cli) Fix state-backend and upgrade regressions (#1163, #1185, #1190, #1191, #1194) +- (cli) Fix `squad --help` silently running the command instead of showing help (#1201) +- (cli) Extend SQUAD_TEAM_ROOT to all resolveSquad() call sites for subprocess compatibility +- (sdk+cli) Fix triage label slug derivation: use `slugify()` instead of `toLowerCase()` so multi-word agent names produce valid GitHub labels (e.g. "Steve Rogers" → `squad:steve-rogers` instead of `squad:steve rogers`). +- (cli) fix(watch): Windows shell:true, shared agent-spawn, round-level fetch (#920, #923) +- (sdk+cli) fix: use TEMPLATE_MANIFEST to drive skill installation instead of wholesale directory copy +- (sdk) Fix squad-commands skill routing and configuration for Copilot integration +- (sdk) State backend hardening: retry with exponential backoff for transient git errors, circuit-breaker to prevent cascading failures, read-only startup verification, and observable error surfacing replacing silent swallowing. +- (cli) fix(watch): 3 UX improvements — round timing output, --log-file tee flag, immediate startup feedback (#2141) +- (sdk+cli) Fix Windows Azure CLI execution and ADO state mapping in squad watch +- (sdk) fix(sdk): wire `squad_route` tool handler to actually create target sessions + +### Changed +- **Communications:** `createCommunicationAdapter` is now async. Downstream consumers building custom adapters must `await` the factory call. Not flagged as breaking per pre-1.0 SemVer. +- (sdk) ADO configurable work item types, area paths, and iteration support (#240) +- (cli) Ship 8 built-in skills with squad init/upgrade (#788) +- (cli) Allow memory diagnostics log level to be configured from `.squad/config.json`. +- (sdk+cli) Enable persistent Ralph — heartbeat cron + healthCheck timer +- (sdk+cli) Squad coordinator now scans all 5 project skill directories: Copilot CLI's 3 +- (sdk+cli) Generic, provider-agnostic scheduler for Squad (#296) — unified schedule.json manifest with LocalPolling and GitHubActions provider adapters, CLI commands (list, run, init, status), schema validation, and cron/interval trigger evaluation. +- (sdk+cli) Harden runtime state tools so write, append, and delete only mutate approved Squad runtime state paths, and refresh prompt templates to require state-tool persistence and literal datetime propagation. +- (cli) Widen changelog-gate coverage for template and scaffolding paths + +### Internal / Tests / Docs +- (cli) docs: point README migration guide links to the published docs site ## [0.9.0] - 2026-03-23 diff --git a/docs/_internal/v0.10.0-CHANGELOG-snapshot.md b/docs/_internal/v0.10.0-CHANGELOG-snapshot.md new file mode 100644 index 000000000..df6c0671a --- /dev/null +++ b/docs/_internal/v0.10.0-CHANGELOG-snapshot.md @@ -0,0 +1,103 @@ +## [0.10.0] — 2026-06-07 + +First stable release since v0.9.4 (April 25). Consumes 97 changesets (sdk: 50, cli: 71). + +### Security +- (cli) iter-9: inject `--yolo --additional-mcp-config @.mcp.json` in all non-interactive copilot spawns; fix path regression from `.copilot/mcp-config.json` (iter-7) to `.mcp.json` (iter-8 canonical location); add fallback warning when `.mcp.json` is absent; add `--yolo` deduplication guard; document Copilot CLI 1.0.59+ folder-trust security gate + +### Performance +- (cli) Add /fleet hybrid dispatch mode for squad watch --execute (#775) — enables parallel issue analysis via Copilot CLI /fleet, 2.9x faster than sequential dispatch for read-heavy work +- (sdk) perf(agents): parallelize charter discovery with concurrency limit to reduce multi-agent load time +- (sdk+cli) perf(resolution): memoize squad-dir lookups; deduplicate squads.json reads to reduce filesystem I/O on repeated resolution calls +- (sdk) perf(scheduler): convert sequential async execution to concurrent with bounded concurrency to improve multi-agent dispatch throughput + +### Added +- (sdk) Add rework rate OTEL metrics (#265) — tracks PR revision patterns as the emerging 5th DORA metric +- (sdk+cli) Add routing.md to squad export/import functionality +- (sdk) Add SkillScriptLoader, handler types, and applySkillHandlers for executable skill handler scripts +- (cli) feat: APM integration — squad skill publish/install + apm.yml in init +- (sdk) feat: Cooperative rate limiting with predictive circuit breaker +- (sdk+cli) Cross-squad orchestration — discovery, delegation, and manifest (#316). Adds manifest schema, `squad discover` / `squad delegate` commands, and runtime module for coordinating work across multiple Squad instances. +- (cli) Add deprecation warnings for tunnel, rc, and REPL commands. The interactive shell (no-args), `squad start`, `squad start --tunnel`, `squad rc`, and `squad rc-tunnel` now emit yellow deprecation notices pointing users to the GitHub Copilot CLI. No behavior changes — all commands still work. +- (cli) docs: add fork contribution workflow to CONTRIBUTING.md +- (cli) Add user-facing documentation for state backends (local, orphan-branch, two-layer) +- (sdk) Add dual-mode deployment support for capabilities routing. +- (sdk+cli) feat: add error-recovery skill for standard agent failure recovery patterns +- (sdk+cli) Add external state storage — move .squad/ out of the working tree (#792) +- (sdk+cli) Add fact-checker as a built-in agent role (#789) +- (cli) Fix squad doctor and upgrade for insiders installs: add .squad/casting/ to ENSURE_DIRECTORIES, scaffold casting defaults from templates with permission-safe fallback, and clarify ESM warnings for global installs. +- (sdk) Sync squad.agent.md roster when agents added to team.md +- (cli) fix(ci): fix multiple CI test failures introduced by PR #1035 coordinator slimming +- (sdk+cli) Warn when squad.agent.md template is missing during upgrade or init instead of silently skipping file creation. Adds `warnings` field to `InitResult` for structured error reporting. +- (sdk+cli) feat(sdk): git-notes + orphan-branch state backends for .squad/ +- (sdk+cli) feat: add iterative-retrieval skill for structured max-3-cycle agent spawning +- (cli) docs: Add KEDA external scaler template for GitHub issue-driven autoscaling +- (cli) feat(cli): Add `squad loop` command — prompt-driven continuous work loop +- (sdk+cli) feat: Machine capability discovery and `needs:*` label-based issue routing +- (sdk+cli) Add `squad init --mcp-frontmatter` to write MCP server config into the Squad agent frontmatter instead of `.copilot/mcp-config.json` for compatible agent harnesses. +- (sdk+cli) feat: add notification-routing skill for pub-sub channel routing +- (sdk+cli) feat: add declarative plugin behavior context proof +- (cli) Add `--notify-level` to control watch round reporting noise (#803) +- (sdk+cli) Add Rai as Squad's third built-in agent — a Responsible AI (RAI) reviewer +- (sdk+cli) feat: add reflect skill for in-session learning capture and mistake prevention +- (sdk+cli) Add `--repo` and `--branch` flags to `squad export` and `squad import` commands, enabling users to push/pull Squad configuration directly to/from a GitHub repository via the GitHub Contents API. +- (sdk+cli) Add retro enforcement skill with Test-RetroOverdue and ceremonies template update. +- (sdk) Add `.squad/.scratch/` directory for organized temp file management (#790) +- (sdk) Add SDK feature parity batch 2 — 64 tests covering manual ceremonies (#27), ceremony cooldown (#28), human team members (#36), constraint budget enforcement (#49 — rate limiter, file-write guards, shell restrictions, PII scrubbing), multi-agent artifact coordination (#50), and builder validation edge cases. +- (sdk) test: SDK feature parity batch 3 — 46 tests for #31, #47, #45, #46 +- (cli) Add `squad upgrade --self` to upgrade the CLI package itself (#798) +- (cli) feat: session init update check with extensible session-init reference +- (cli) feat: add squad-commands skill for in-chat command discovery +- (sdk+cli) feat: add SQUAD_HOME env var and preset system +- (cli) Fix Windows spawn EINVAL in watch capabilities by adding `shell: true` to `execFile()` calls in monitor-teams, monitor-email, retro, and decision-hygiene capabilities. Add Copilot CLI preflight check to `squad doctor` and monitor capabilities so missing `gh copilot` extension is flagged early. Improve team hire confirmation UX to show member names inline with the prompt. (closes #920, closes #880, closes #1107) +- (sdk) Bump `@github/copilot-sdk` from `^0.1.32` to `^0.3.0` to fix ESM module resolution error (ERR_MODULE_NOT_FOUND for vscode-jsonrpc/node). Add explicit GitHub repo config support in `.squad/config.json` (`{ "github": { "owner": "...", "repo": "..." } }`) so platform adapter prefers user-specified repo over auto-detection from origin remote. (closes #1062, closes #905) +- (sdk+cli) Add delete() and append() to StateBackend interface; add resolveSquadState() entry point; add StateBackendStorageAdapter; add git-notes agent protocol templates +- (sdk) feat(sdk): Add Microsoft Teams communication adapter +- (sdk+cli) feat: add tiered-memory skill for hot/cold/wiki agent context management +- (cli) feat(watch): circuit breaker integration for rate limit protection (#515) +- (cli) feat(watch): health check — show running watch instance status (#808) +- (cli) Add --verbose flag to squad watch for debugging empty boards and silent failures (#781) + +### Fixed +- (sdk+cli) Fix hardcoded "Brady" in template files — LLMs now use actual git username instead of example name (closes #977) +- (cli) Fix changelog-gate CI to accept .changeset/ files as alternative to direct CHANGELOG.md edits +- (sdk+cli) fix: bump CLI version to 0.9.7-preview; align E2E skill and policy gate with CONTRIBUTING.md +- (sdk+cli) fix: context overflow sentinel and coordinator size reduction (retroactive for #1035) +- (sdk+cli) Fix coordinator and Scribe templates so spawned agents receive and write the resolved current datetime instead of placeholder text. +- (cli) fix(cli): revert detect-squad-dir to zero-dependency bootstrap +- (cli) fix: restore CI green on dev — 25 regression fixes + 6 test corrections +- (cli) Fix export/import producing blank decisions.md and team.md files. Export now includes these files in the manifest, and import restores their content. +- (cli) Fix runtime commands to correctly resolve externalized state paths +- (sdk+cli) Fix 5 bugs: dotted repo names, icon spacing, board owner, charter passing, missing playbooks +- (cli) fix: `/init` with no args now accepts follow-up message as cast prompt, and `createTeam` correctly creates `team.md`/`routing.md` in fresh projects +- (cli) fix(nap): account for separator newlines in decision archival budget +- (cli) fix(cli): wire --team-root / SQUAD_TEAM_ROOT into squad resolution for nap, status, and cost commands (#734) +- (cli) fix: CLI no longer bails when configured is false; starts onboarding session instead (#843) +- (cli) fix(coordinator): resolve externalized state, teamRoot, stale work, and cleanup loops +- (sdk+cli) Fix permission handler to use `approve-once` instead of deprecated `approved` kind, aligning with Copilot CLI v1.0.54+ permission contract +- (cli) Fix post-init message to recommend `copilot --agent squad` instead of deprecated `squad` command (closes #1034, closes #1007) +- (sdk+cli) Fix state-backend and upgrade regressions (#1163, #1185, #1190, #1191, #1194) +- (cli) Fix `squad --help` silently running the command instead of showing help (#1201) +- (cli) Extend SQUAD_TEAM_ROOT to all resolveSquad() call sites for subprocess compatibility +- (sdk+cli) Fix triage label slug derivation: use `slugify()` instead of `toLowerCase()` so multi-word agent names produce valid GitHub labels (e.g. "Steve Rogers" → `squad:steve-rogers` instead of `squad:steve rogers`). +- (cli) fix(watch): Windows shell:true, shared agent-spawn, round-level fetch (#920, #923) +- (sdk+cli) fix: use TEMPLATE_MANIFEST to drive skill installation instead of wholesale directory copy +- (sdk) Fix squad-commands skill routing and configuration for Copilot integration +- (sdk) State backend hardening: retry with exponential backoff for transient git errors, circuit-breaker to prevent cascading failures, read-only startup verification, and observable error surfacing replacing silent swallowing. +- (cli) fix(watch): 3 UX improvements — round timing output, --log-file tee flag, immediate startup feedback (#2141) +- (sdk+cli) Fix Windows Azure CLI execution and ADO state mapping in squad watch +- (sdk) fix(sdk): wire `squad_route` tool handler to actually create target sessions + +### Changed +- **Communications:** `createCommunicationAdapter` is now async. Downstream consumers building custom adapters must `await` the factory call. Not flagged as breaking per pre-1.0 SemVer. +- (sdk) ADO configurable work item types, area paths, and iteration support (#240) +- (cli) Ship 8 built-in skills with squad init/upgrade (#788) +- (cli) Allow memory diagnostics log level to be configured from `.squad/config.json`. +- (sdk+cli) Enable persistent Ralph — heartbeat cron + healthCheck timer +- (sdk+cli) Squad coordinator now scans all 5 project skill directories: Copilot CLI's 3 +- (sdk+cli) Generic, provider-agnostic scheduler for Squad (#296) — unified schedule.json manifest with LocalPolling and GitHubActions provider adapters, CLI commands (list, run, init, status), schema validation, and cron/interval trigger evaluation. +- (sdk+cli) Harden runtime state tools so write, append, and delete only mutate approved Squad runtime state paths, and refresh prompt templates to require state-tool persistence and literal datetime propagation. +- (cli) Widen changelog-gate coverage for template and scaffolding paths + +### Internal / Tests / Docs +- (cli) docs: point README migration guide links to the published docs site diff --git a/package-lock.json b/package-lock.json index 48d179e9e..1a7070ec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@bradygaster/squad", - "version": "0.9.6-preview.14", + "version": "0.10.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@bradygaster/squad", - "version": "0.9.6-preview.14", + "version": "0.10.0", "license": "MIT", "workspaces": [ "packages/*" diff --git a/package.json b/package.json index e5789749f..77bd9a13c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bradygaster/squad", - "version": "0.9.6-preview.14", + "version": "0.10.0", "private": true, "description": "Squad — Programmable multi-agent runtime for GitHub Copilot, built on @github/copilot-sdk", "type": "module", diff --git a/packages/squad-cli/CHANGELOG.md b/packages/squad-cli/CHANGELOG.md new file mode 100644 index 000000000..de2f76cdc --- /dev/null +++ b/packages/squad-cli/CHANGELOG.md @@ -0,0 +1,555 @@ +# @bradygaster/squad-cli + +## 0.10.0 + +### Minor Changes + +- 6a72634: Add routing.md to squad export/import functionality + + The routing.md file is now included when exporting and importing Squad configurations. + This preserves the full routing context (tables, comments, principles) alongside the + structured routing rules that were already exported. + +- 6e72c8a: feat: APM integration — squad skill publish/install + apm.yml in init + + Implements #824. Adds `squad skill publish/install/list` commands and generates `apm.yml` on `squad init`. + +- 53eddac: Ship 8 built-in skills with squad init/upgrade (#788) + + New skills distributed automatically on `squad init` and `squad upgrade`: + + - **error-recovery** — graceful failure handling patterns + - **secret-handling** — credential safety and secrets management + - **git-workflow** — branch management and commit conventions + - **session-recovery** — checkpoint and recovery patterns + - **reviewer-protocol** — code review gate patterns + - **test-discipline** — test-first discipline and coverage + - **agent-collaboration** — multi-agent handoff patterns + - **squad-conventions** — (already shipped, now part of curated set) + + All skills are squad-owned (`overwriteOnUpgrade: true`) and update on upgrade. + +- 7f9a878: Add cleanup watch capability for stale file housekeeping (#791) + + - New `cleanup` capability in the `housekeeping` phase + - Clears `.squad/.scratch/` (all ephemeral temp files) + - Archives orchestration-log and session-log entries older than 30 days + - Warns about stale decision inbox files (>7 days) + - Configurable: `everyNRounds` (default: 10), `maxAgeDays` (default: 30) + - 12 new tests + +- 5826555: Cross-squad orchestration — discovery, delegation, and manifest (#316). Adds manifest schema, `squad discover` / `squad delegate` commands, and runtime module for coordinating work across multiple Squad instances. +- 9c3156a: feat: add error-recovery skill for standard agent failure recovery patterns +- 37def62: Add external state storage — move .squad/ out of the working tree (#792) + + - New `stateLocation: 'external'` option in `.squad/config.json` + - `resolveExternalStateDir()` resolves state under the platform-specific global Squad directory (`resolveGlobalSquadPath()`) + - `deriveProjectKey()` generates a stable key from the repo path (cross-platform) + - `resolveSquadPaths()` honors external state location + - `squad externalize` moves state out, `squad internalize` moves it back + - State survives branch switches, invisible to `git status`, never pollutes PRs + - Thin `.squad/config.json` marker stays in repo (gitignored) + - Path traversal protection on projectKey + - 12 new tests + +- 9a53769: Add fact-checker as a built-in agent role (#789) + + - New `fact-checker` role in the engineering role catalog (emoji: 🔍, category: quality) + - Charter template at `templates/fact-checker-charter.md` with verification methodology + - Added to `AGENT_TEMPLATES` for init scaffolding + - Template manifest entry for init/upgrade distribution + - Routing patterns: fact-check, verify, validate, audit, double-check, hallucination, devil's advocate + +- 5996db4: Add /fleet hybrid dispatch mode for squad watch --execute (#775) — enables parallel issue analysis via Copilot CLI /fleet, 2.9x faster than sequential dispatch for read-heavy work +- 7f9a878: feat(sdk): git-notes + orphan-branch state backends for .squad/ + + Adds git-native state storage backends as alternatives to the local (disk) + approach: + + - **orphan-branch** (`squad-state`): Dedicated orphan branch with no common + ancestor. State files never appear in main. + - **two-layer** (notes + orphan): Git notes as best-effort commit annotations + plus orphan branch for durable state. Recommended for teams. + + Configure via `.squad/config.json`: `{ "stateBackend": "two-layer" }` or + the `--state-backend` CLI flag. + +- f8347d8: iter-9: inject `--yolo --additional-mcp-config @.mcp.json` in all non-interactive copilot spawns; fix path regression from `.copilot/mcp-config.json` (iter-7) to `.mcp.json` (iter-8 canonical location); add fallback warning when `.mcp.json` is absent; add `--yolo` deduplication guard; document Copilot CLI 1.0.59+ folder-trust security gate +- 87e9381: feat: add iterative-retrieval skill for structured max-3-cycle agent spawning +- efb56ac: feat(cli): Add `squad loop` command — prompt-driven continuous work loop + + New `squad loop` command reads a `loop.md` file and runs it as a continuous work loop. + No GitHub issues required — the prompt is the work driver. Includes `--init` to scaffold + a boilerplate loop file, frontmatter validation, and composable capability flags. + +- 8d49066: feat: Machine capability discovery and `needs:*` label-based issue routing + + Added capability filtering to Ralph's watch command. Issues with `needs:*` labels + (e.g., `needs:gpu`, `needs:browser`) are only processed by Ralph instances whose + machine has those capabilities declared in `machine-capabilities.json`. + + This enables multi-machine Squad deployments where different machines handle + different types of work based on their available tooling. + + Closes #514 + +- 900d2e4: Add `squad init --mcp-frontmatter` to write MCP server config into the Squad agent frontmatter instead of `.copilot/mcp-config.json` for compatible agent harnesses. +- a9c06b0: feat: add notification-routing skill for pub-sub channel routing +- 32d2a23: Enable persistent Ralph — heartbeat cron + healthCheck timer + + - Enable cron schedule in squad-heartbeat.yml (all 5 sync locations) + - Enable RalphMonitor healthCheck timer (previously commented out pre-migration) + - Add platform detection tests for getRalphScanCommands (GitHub/ADO/Planner) + - Add healthCheck timer tests with fake timers (start/stop/interval/stale detection) + +- 7f9a878: Add `--notify-level` to control watch round reporting noise (#803) + + - `--notify-level important` (default): only print rounds with actual work items + - `--notify-level all`: print every round including empty (old behavior) + - `--notify-level none`: suppress all round output + - Add machine name (`os.hostname()`) and repo name to round headers for attribution + (shown in round headers when the board has items, and in "Board is clear" message) + - Configurable via `.squad/config.json` watch section: `"notifyLevel": "important"` + - Empty rounds silenced by default — no more "Round 160, Round 161" spam + +- 6a01eef: Add Rai as Squad's third built-in agent — a Responsible AI (RAI) reviewer + + - Rai is always on the roster (like Scribe and Ralph), exempt from casting + - Traffic light verdict model: 🟢 Green (proceed), 🟡 Yellow (advisory), 🔴 Red (blocking) + - Background mode by default — only blocks on critical RAI violations + - Phase 1 high-signal checks: credentials, injection, harmful content, bias, PII + - New templates: Rai-charter.md, rai-policy.md + - New `.squad/rai/` directory with policy.md and audit-trail.md + - Tiered opt-out model (cannot disable critical checks) + +- 9083085: feat: add reflect skill for in-session learning capture and mistake prevention +- 7beb854: Add `--repo` and `--branch` flags to `squad export` and `squad import` commands, enabling users to push/pull Squad configuration directly to/from a GitHub repository via the GitHub Contents API. +- aa91ba4: Add retro enforcement skill with Test-RetroOverdue and ceremonies template update. + + - New skill: retro-enforcement - coordinator integration pattern for automated retro cadence enforcement + - Action items tracked as GitHub Issues (not markdown checklists) + - Production data: 0% to 100% completion rate after switching formats + - Test-RetroOverdue PowerShell function detects overdue retros and blocks work queue + - Ceremonies template updated with enforcement-aware retrospective definition + +- f090b3a: Add `squad upgrade --self` to upgrade the CLI package itself (#798) + + - `squad upgrade --self` → installs `@bradygaster/squad-cli@latest` (stable) + - `squad upgrade --self --insider` → installs `@bradygaster/squad-cli@insider` (prerelease) + - After self-upgrade, automatically continues with repo upgrade to apply new templates + - Detects package manager (npm/pnpm/yarn) from npm_config_user_agent + - Clear error on permission denied (suggests sudo or npx) + - Help text updated with new flags + +- 88ab159: feat: session init update check with extensible session-init reference + + Adds a Session Init block to squad.agent.md that runs Step 1 (Update Check) + at session start. When a newer @bradygaster/squad-cli version exists for the + user's channel (latest/insider/preview), appends a notice to the greeting. + Respects SQUAD_NO_UPDATE_CHECK=1 kill switch. + + Adds `.squad-templates/session-init-reference.md` with the full update-check + procedure (channel detection, hybrid cache strategy, greeting format) and + registers it in TEMPLATE_MANIFEST so `squad upgrade` keeps it current. + + Also adds squad-version-check SKILL.md to .copilot/skills with internals + knowledge about version stamping and the npm registry probe mechanism. + + Also fixes pre-existing CI failures: adds Commit step to scribe-charter.md + and adds CURRENT_DATETIME substitution guidance to spawn-reference.md. + +- fe1e7e8: Squad coordinator now scans all 5 project skill directories: Copilot CLI's 3 + official project paths — `.github/skills/`, `.claude/skills/`, `.agents/skills/` + (per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills) + — plus Squad's existing conventions `.squad/skills/` and `.copilot/skills/`. + Precedence: `.squad/skills/` > `.copilot/skills/` > `.github/skills/` > + `.claude/skills/` > `.agents/skills/` (dedup by directory name). Personal + paths (`~/.copilot/skills/`, `~/.agents/skills/`) are deliberately excluded + from explicit routing — Copilot CLI injects them ambiently. This closes a gap + where skills placed in `.github/skills/` (a common location alongside other + `.github/` tooling) were loaded by Copilot CLI but invisible to Squad's + coordinator-attached skill-aware routing. +- eb17e15: feat: add squad-commands skill for in-chat command discovery + + Adds a categorized menu skill (`skills/squad-commands/SKILL.md`) that the + coordinator reads when the user asks "squad commands", "help", or "what can + squad do". Also adds a routing row and greeting tip in squad.agent.md, and + registers the template in TEMPLATE_MANIFEST with overwriteOnUpgrade=true. + + Also fixes pre-existing CI failures: adds Commit step to scribe-charter.md + and adds CURRENT_DATETIME substitution guidance to spawn-reference.md. + +- ef30286: feat: add SQUAD_HOME env var and preset system + + - Add `SQUAD_HOME` environment variable support for a roaming squad root directory + - Add preset system for reusable agent configurations (list, show, apply, init) + - Ship a default built-in preset with 5 agents (lead, reviewer, devrel, security, docs) + - Add `squad preset` CLI command with list, show, apply, and init subcommands + - Resolves #1038 + +- 5720705: Generic, provider-agnostic scheduler for Squad (#296) — unified schedule.json manifest with LocalPolling and GitHubActions provider adapters, CLI commands (list, run, init, status), schema validation, and cron/interval trigger evaluation. +- e11b5d3: feat: add tiered-memory skill for hot/cold/wiki agent context management +- bf597cb: feat(watch): circuit breaker integration for rate limit protection (#515) + + Adds GitHub API rate limit protection to Ralph's watch command via + the Predictive Circuit Breaker from PR #518. + + **What changed (additive patch — existing flow untouched):** + + - `gh-cli.ts`: Added `ghRateLimitCheck()` and `isRateLimitError()` helpers + - `watch.ts`: Added `CircuitBreakerState` type + persistence helpers + - `watch.ts`: Added `executeRound()` wrapper that gates the existing + `runCheck()` call through pre-flight quota checks + - `watch.ts`: Added `roundInProgress` flag to prevent overlapping rounds + + **Circuit breaker state machine:** + + - CLOSED → OPEN: When traffic light is red or predictor says exhaustion imminent + - OPEN → HALF-OPEN: After cooldown expires (exponential: 2m → 4m → 8m → ... → 30m cap) + - HALF-OPEN → CLOSED: After 2 consecutive successful rounds + - HALF-OPEN → OPEN: On rate limit error during probe + + State persists to `.squad/ralph-circuit-breaker.json` across restarts. + + **Tests:** 16 new tests covering state transitions, race condition guard, + predictive integration, and `isRateLimitError` detection. + +- 7f9a878: feat(watch): health check — show running watch instance status (#808) + + Adds `squad watch --health` to display the status of a running watch + instance: PID, uptime, auth account, capabilities, and auth drift + detection. Writes `.squad/.watch-pid.json` at startup for instance + tracking. Detects and cleans up stale PID files from crashed instances. + +- a22e087: Add --verbose flag to squad watch for debugging empty boards and silent failures (#781) + +### Patch Changes + +- 9451e66: Add deprecation warnings for tunnel, rc, and REPL commands. The interactive shell (no-args), `squad start`, `squad start --tunnel`, `squad rc`, and `squad rc-tunnel` now emit yellow deprecation notices pointing users to the GitHub Copilot CLI. No behavior changes — all commands still work. +- f0c02c9: docs: add fork contribution workflow to CONTRIBUTING.md + + Closes five gaps discovered during PR #217: + + - Fork-first setup instructions (fork → clone → upstream remote) + - PR must target `dev` branch, not `main` (`gh pr create --base dev`) + - Changeset is a required step in the PR process checklist + - `bradygaster/dev` now correctly described as the PR target for all contributions + - New "Keeping Your Fork in Sync" section with rebase-on-upstream/dev instructions + +- 7a5b180: Add user-facing documentation for state backends (local, orphan-branch, two-layer) +- 36eed05: Fix hardcoded "Brady" in template files — LLMs now use actual git username instead of example name (closes #977) +- d8c1382: Fix changelog-gate CI to accept .changeset/ files as alternative to direct CHANGELOG.md edits +- 8c33f9f: fix: bump CLI version to 0.9.7-preview; align E2E skill and policy gate with CONTRIBUTING.md + + The insider publish workflow stamped `@bradygaster/squad-cli` at `0.9.6-build.4`, + which violates the prerelease version policy gate. Per CONTRIBUTING.md, the correct + local dev version is `{next-version}-preview`. + + - `packages/squad-cli/package.json`: `0.9.6-build.4` → `0.9.7-preview` + - All 4 copies of `e2e-template-testing/SKILL.md` (root `templates/`, + `packages/squad-sdk/templates/`, `packages/squad-cli/templates/`, + `.squad-templates/`): + - **Build commands** aligned with CONTRIBUTING.md (lines 253–256): use workspace + flags `npm run build -w packages/squad-sdk && npm run build -w packages/squad-cli` + and `npm link -w packages/squad-cli` instead of shell `cd` + bare `npm run build` + - **Version verify text** updated to version-agnostic `x.y.z-preview` placeholder + with an explicit note that the `-preview` suffix is required, linking to + CONTRIBUTING.md for the full local dev setup + - `.github/workflows/squad-ci.yml` — Prerelease Version Guard: relaxed regex from + `/-/` (any hyphen) to `/-/ && not /^\d+\.\d+\.\d+-preview$/` so the CONTRIBUTING.md- + sanctioned `-preview` suffix is allowed while all other prerelease tags (e.g. + `-build.4`, `-alpha`, `-beta`) are still blocked + +- 490adf3: fix: context overflow sentinel and coordinator size reduction (retroactive for #1035) + + `squad.agent.md` was ~95.8KB and could be silently dropped from context in long sessions, degrading the coordinator to vanilla Copilot with no safety rails. + + Changes shipped in PR #1035 (merged without changeset): + + - **Canary sentinel** — `SQUAD_COORDINATOR_CANARY_a8f3` token appended to `squad.agent.md`; `copilot-instructions.md` checks for it and warns if the coordinator was dropped from context + - **Coordinator slimming** — `squad.agent.md` reduced ~42% (95.8KB → ~55KB) by extracting to on-demand reference files: `spawn-reference.md`, `after-agent-reference.md`, `model-selection-reference.md`, `ralph-reference.md`, `worktree-reference.md`, `client-compatibility-reference.md` + - **Scribe charter extraction** — Scribe's inline section moved from `squad.agent.md` to a standalone `scribe-charter.md` + - **E2E skill overhaul** — Fast-fail rules, PII protection, anti-skip enforcement, live progress tracking comment (updated per step), duration tracking, Windows encoding fix, `--allow-all-tools` documentation, progressive verdicting, agent run time budget + - **Build fix** — CLI dep changed from `@bradygaster/squad-sdk: >=0.9.0` to `>=0.9.0-0` so npm workspace resolution uses the local prerelease package instead of a stale published version + + All 4 template locations synced: `.squad-templates/`, `templates/`, `packages/squad-cli/templates/`, `packages/squad-sdk/templates/`. + + Closes #1017 + +- e5f4ca5: Fix coordinator and Scribe templates so spawned agents receive and write the resolved current datetime instead of placeholder text. +- 8c807d1: fix(cli): revert detect-squad-dir to zero-dependency bootstrap + + The StorageProvider refactor (26047dc5) accidentally converted this bootstrap utility from raw node:fs to FSStorageProvider. This file runs before the SDK is loaded and must not depend on @bradygaster/squad-sdk. Adds regression guard test. + +- 67b3578: fix: restore CI green on dev — 25 regression fixes + 6 test corrections + + Commit `4ecc244` ("feat: Squad Remote Control") rewrote `cli-entry.ts` and + silently dropped multiple P0 bug fixes. Commit `72ffcb1` ("unified status + display") introduced a TUI regression in AgentPanel. This changeset restores + all dropped behaviour and corrects test expectations that never matched the + implementation. + + **Implementation regressions fixed (cli-entry.ts):** + + - Bare semver output: `squad --version` now prints `0.x.y` not `squad 0.x.y` + - Whitespace args guard: `squad` / `squad ` shows brief help and exits 0 + - `NODE_NO_WARNINGS=1` set before first import to suppress ExperimentalWarning + - `squad doctor` hint restored in unknown-command error messages + - Help lines that exceeded 80 chars wrapped to continuation lines + + **Implementation regressions fixed (shell/index.ts):** + + - First-run (no `.squad/`) on non-TTY now outputs a welcome/get-started message + instead of a TTY error, matching E2E test expectations + + **Implementation regressions fixed (AgentPanel.tsx):** + + - Completion flash correctly shows `✓ Done`; was showing `✓ [IDLE]` because + the status-label condition was not gated on the flash state + + **Test corrections (expectations that never matched implementation):** + + - `repl-ux.test.ts`: `toContain('ready')` → `toContain('[idle]')` + - `human-journeys.test.ts`: `Scaffold ready` → `Your team is ready`; + `copilot session` → `squad` + - `cli/init.test.ts` + `repl-ux-fixes.test.ts`: wrong gitattributes path fixed + - `ux-gates.test.ts`: two aspirational grouped-help tests replaced with `it.todo` + - `first-run-gating.test.ts`: banner spacer regex updated to match current source form + - `consult-command.feature`: expected text updated to match current CLI output + - `status-extended.feature`: exit code corrected (`1` → `0`) for non-squad dir + - `docs-build.test.ts`: `beforeAll` hook given explicit 30 s timeout to avoid + flaky timeout failures under parallel test execution + - `journey-next-day.test.ts`: added `tick(50)` between session saves to prevent + race condition when both sessions receive the same `lastActiveAt` timestamp + +- 2f807d6: Fix squad doctor and upgrade for insiders installs: add .squad/casting/ to ENSURE_DIRECTORIES, scaffold casting defaults from templates with permission-safe fallback, and clarify ESM warnings for global installs. +- e3b880f: Fix export/import producing blank decisions.md and team.md files. Export now includes these files in the manifest, and import restores their content. +- 0d124b9: Fix runtime commands to correctly resolve externalized state paths +- 42c9dd3: Fix 5 bugs: dotted repo names, icon spacing, board owner, charter passing, missing playbooks +- f8ea328: fix: `/init` with no args now accepts follow-up message as cast prompt, and `createTeam` correctly creates `team.md`/`routing.md` in fresh projects + + Two related bugs in the TUI init flow: + + 1. After `/init` (no args) showed guidance text, the user's follow-up message hit the "No Squad team found" guard instead of starting team casting. Fixed by tracking `awaitingInitPrompt` state in `App.tsx` and bypassing the team-file guard in `handleDispatch` when `skipCastConfirmation` is explicitly set. + + 2. After confirming a team proposal, `createTeam` silently skipped creating `team.md` and `routing.md` in a fresh project (no `.squad/` directory), causing the coordinator to immediately say "no team yet" after showing "Team hired!". Fixed with else-branches that create both files from scratch when they don't exist. + +- bdfa21a: fix(nap): account for separator newlines in decision archival budget + + The budget calculation in archiveDecisions() did not account for the newline + separators added during content reassembly. This caused the final recentContent + to exceed DECISION_THRESHOLD even after archival. Fix adds reassemblyOverhead + and per-entry separator bytes to the budget calculation. + + Closes #123 + +- 6f9d965: fix(cli): wire --team-root / SQUAD_TEAM_ROOT into squad resolution for nap, status, and cost commands (#734) + + Commands that resolve .squad/ now respect the SQUAD_TEAM_ROOT env var (set by --team-root flag), + fixing subprocess invocations (e.g. Copilot CLI bang commands) where process.cwd() differs from + the interactive shell. Also improves the nap error message to show the searched directory. + +- 7b52e29: fix: CLI no longer bails when configured is false; starts onboarding session instead (#843) +- 00c8aea: fix(coordinator): resolve externalized state, teamRoot, stale work, and cleanup loops + + Fixes 4 P1 coordinator bugs where squad.agent.md would incorrectly enter Init Mode + in satellite/externalized repos (#1116, #1127), agents would work on stale/closed items + (#1125), and spawned agents would loop infinitely in post-work cleanup (#1067). + +- 70a3781: Fix permission handler to use `approve-once` instead of deprecated `approved` kind, aligning with Copilot CLI v1.0.54+ permission contract +- 1d3c3ea: Fix post-init message to recommend `copilot --agent squad` instead of deprecated `squad` command (closes #1034, closes #1007) +- 457f12f: docs: point README migration guide links to the published docs site +- 490adf3: fix(ci): fix multiple CI test failures introduced by PR #1035 coordinator slimming + + PR #1035 extracted Scribe and spawn-template content out of `squad.agent.md` into + standalone reference files but did not update the CI tests. Two tests failed: + + **`test/ci/scribe-template.test.ts`** — was reading from `squad.agent.md` with anchors + that no longer exist. Fixed to read from `scribe-charter.md` with: + + - Number- and format-agnostic end-marker in `extractScribeTaskBlock` + - Numbered-line assertions (verify phrases appear on actual `\d+.` list items) + - Corrected file header comment (HEALTH REPORT and size thresholds ARE present) + - New tests: HEALTH REPORT emission documented, Tier 1 (20KB) and Tier 2 (50KB) + archival thresholds documented (10 tests total, was 7) + + **`test/ci/datetime-template.test.ts`** — was counting `CURRENT_DATETIME:` lines in + `squad.agent.md` only, expecting ≥4. After slimming only 2 remain there; the rest + moved to `spawn-reference.md` and `after-agent-reference.md`. Fixed to combine all + coordinator-owned template files for spawn-template assertions. + +- 27f07cf: Warn when squad.agent.md template is missing during upgrade or init instead of silently skipping file creation. Adds `warnings` field to `InitResult` for structured error reporting. +- 09cd6c1: Fix state-backend and upgrade regressions (#1163, #1185, #1190, #1191, #1194) + + **Bug A (P0) — Permission contract mismatch** (#1191) + The Copilot SDK changed the valid permission result `kind` from `"approved"` to + `"approve-once"`. Squad was still returning `{ kind: 'approved' }`, causing all + agent sessions to fail permission checks immediately. Fixed in: + + - `cli/shell/index.ts` — `approveAllPermissions` handler now returns `{ kind: 'approve-once' }` + - `adapter/types.ts` — `SquadPermissionRequestResult.kind` union includes `'approve-once'` + - `adapter/client.ts` — error hint updated to reference the correct `kind` value + + **Bug B (P1) — Hard-throw in `resolveStateBackend()` when explicit backend fails** (#1185, #1190) + When a backend configured in `config.json` failed to initialize (e.g., no git repo + available), Squad threw a fatal error and refused to start. Now always warns and + falls back to `local` so operators can fix config without losing work. + + **Bug C (P1) — Silent git-notes→two-layer migration** (#1163) + `normalizeBackendType()` silently mapped `'git-notes'` to `'two-layer'` with no + user notification. Now emits a `console.warn()` directing users to update their + `config.json`. + + **Bug F (P3) — Windows `toRelative()` drive-letter case mismatch** + `StateBackendStorageAdapter.toRelative()` used a simple string prefix comparison + after normalizing separators. On Windows, `C:\` vs `c:\` drive-letter case + differences caused the prefix check to fail, returning full absolute paths as + git-notes keys (corruption). Now uses `path.resolve()` and case-insensitive + comparison on `process.platform === 'win32'`. + + **Issue #1194 — Externalized state paths not followed by runtime commands** + Adds `effectiveSquadDir()` and `resolveStateDir()` helpers that follow the + `stateLocation: 'external'` marker in `.squad/config.json`. Updates `loop`, + `watch`, `plugin`, `doctor` commands and `shell` (lifecycle, coordinator, index) + to use the effective state dir for reading `team.md`, `routing.md`, `agents/`, + `plugins/`, and other state files. + +- 6760b6e: Fix `squad --help` silently running the command instead of showing help (#1201) + + Previously, passing `--help` or `-h` after a subcommand (e.g. `squad init --help`, + `squad triage --help`, `squad doctor --help`) was silently dropped and the command + would execute for real — sometimes with destructive side effects (init scaffolded + files into the cwd, triage/watch started a polling loop). Only `squad loop --help` + and `squad state-mcp --help` were intercepting the flag. + + The CLI now intercepts `--help`/`-h` for every registered subcommand in one place + at the top of the router and prints command-specific help via a new + `printCommandHelp(cmd, version)` helper. Unrecognized commands fall back to a + friendly "see `squad help`" message. No side effects are triggered. + +- e4a49f1: Extend SQUAD_TEAM_ROOT to all resolveSquad() call sites for subprocess compatibility +- 2129ad7: Fix triage label slug derivation: use `slugify()` instead of `toLowerCase()` so multi-word agent names produce valid GitHub labels (e.g. "Steve Rogers" → `squad:steve-rogers` instead of `squad:steve rogers`). + + Pre-create all `squad:{member}` labels at watch startup via `ensureTag()` so `gh issue edit --add-label` never fails on missing labels. + +- cb57268: fix(watch): Windows shell:true, shared agent-spawn, round-level fetch (#920, #923) + + Three fixes for the watch --execute subsystem: + + 1. Added shell: IS_WINDOWS to all 37+ execFile calls so commands resolve + through PATH on Windows (fixes spawn EINVAL errors). + + 2. Created shared agent-spawn.ts module replacing 7 copy-pasted + buildAgentCommand() implementations. Default changed from deprecated + gh copilot to standalone copilot CLI. + + 3. Added RoundData shared fetch — issues and PRs fetched once per round + instead of per-capability, reducing API calls from ~40 to ~2 per round. + +- 677b7cf: docs: Add KEDA external scaler template for GitHub issue-driven autoscaling + + New template documenting how to use keda-copilot-scaler for scaling + agent pods to zero when idle, with rate-limit-aware polling. + + Closes #516 + +- a299b3c: fix: use TEMPLATE_MANIFEST to drive skill installation instead of wholesale directory copy + + Both sdkInitSquad() and syncAllSkills() previously copied the entire templates/skills/ + directory, ignoring the curated 8-skill subset declared in TEMPLATE_MANIFEST. + This meant all 37+ template skills shipped on every init/upgrade, and + overwriteOnUpgrade was never consulted. + + Now both code paths iterate TEMPLATE_MANIFEST entries: + + - init (SDK): only the 8 manifest skills are copied on first init + - upgrade (CLI): syncAllSkills() reads manifest entries, respects overwriteOnUpgrade + + Fixes #833 + +- 244554c: Allow memory diagnostics log level to be configured from `.squad/config.json`. +- 10f5036: perf(resolution): memoize squad-dir lookups; deduplicate squads.json reads to reduce filesystem I/O on repeated resolution calls +- 3bd1843: feat: add declarative plugin behavior context proof + + Adds static plugin metadata, lifecycle state, runtime context injection, + declarative provider contracts, and behavior simulations for Graphify, + MemPalace, and Index Server plugin samples. Enabled plugins can now contribute + installed static guidance and typed memory/knowledge provider summaries to + spawned-agent prompts while preserving the no-execution security boundary. + +- a3419b5: Fix Windows spawn EINVAL in watch capabilities by adding `shell: true` to `execFile()` calls in monitor-teams, monitor-email, retro, and decision-hygiene capabilities. Add Copilot CLI preflight check to `squad doctor` and monitor capabilities so missing `gh copilot` extension is flagged early. Improve team hire confirmation UX to show member names inline with the prompt. (closes #920, closes #880, closes #1107) +- bc86668: Add delete() and append() to StateBackend interface; add resolveSquadState() entry point; add StateBackendStorageAdapter; add git-notes agent protocol templates + + - Add `delete()` and `append()` methods to the `StateBackend` interface + - Implement delete/append for all three backends (local, orphan, two-layer) + - Fix orphan backend append to preserve trailing whitespace via readUntrimmed() + - Add `SquadStateContext` interface and `resolveSquadState()` factory in resolution module + - Add `StateBackendStorageAdapter` — bridges StateBackend as a StorageProvider so SDK modules that accept `storage: StorageProvider` work with git-notes and orphan backends + - Add `storage` field to `SquadStateContext` — local uses FSStorageProvider directly, orphan/two-layer use the adapter + - Export `StateBackendStorageAdapter` from SDK public API + - Wire `resolveSquadState()` into CLI entry so the state backend is resolved once at startup + - Pass pre-resolved `stateContext` through to watch config to avoid redundant resolution + - Add `notes-protocol.md` template — agent contract for git-notes state (namespaces, JSON schema, fetch/push, conflict handling) + - Add `scripts/notes/fetch.ps1` template — fetch notes + one-time refspec setup + merge after conflict + - Add `scripts/notes/write-note.ps1` template — agent helper for writing notes with JSON validation and push retry + - Update state-backends docs with "Using with Copilot CLI Sessions" section (copilot-instructions snippet, promotion flow, template index) + - This is the SDK foundation for making state backends squad-wide (Phase 1) + +- 84872b1: Harden runtime state tools so write, append, and delete only mutate approved Squad runtime state paths, and refresh prompt templates to require state-tool persistence and literal datetime propagation. +- fa76432: fix(watch): 3 UX improvements — round timing output, --log-file tee flag, immediate startup feedback (#2141) +- 89db44d: Widen changelog-gate coverage for template and scaffolding paths + + Previously, the changelog gate only required a changeset for `packages/squad-(sdk|cli)/src/` changes, so template and scaffolding updates under `packages/squad-(sdk|cli)/templates/`, `.squad-templates/`, top-level `templates/`, and agent charters under `.squad/agents/*/charter.md` could reach users with no release-note entry. This widens the gate to those paths so user-facing template and scaffolding changes are no longer silently omitted from release notes. Closes #1156. + +- a543f93: Fix Windows Azure CLI execution and ADO state mapping in squad watch +- Updated dependencies [a1fcdb8] +- Updated dependencies [6a72634] +- Updated dependencies [ba8d8f7] +- Updated dependencies [1446050] +- Updated dependencies [7f86e0e] +- Updated dependencies [5826555] +- Updated dependencies [dafc495] +- Updated dependencies [9c3156a] +- Updated dependencies [37def62] +- Updated dependencies [9a53769] +- Updated dependencies [36eed05] +- Updated dependencies [8c33f9f] +- Updated dependencies [490adf3] +- Updated dependencies [e5f4ca5] +- Updated dependencies [42c9dd3] +- Updated dependencies [70a3781] +- Updated dependencies [d8c1382] +- Updated dependencies [27f07cf] +- Updated dependencies [09cd6c1] +- Updated dependencies [2129ad7] +- Updated dependencies [7f9a878] +- Updated dependencies [87e9381] +- Updated dependencies [8d49066] +- Updated dependencies [a299b3c] +- Updated dependencies [900d2e4] +- Updated dependencies [a9c06b0] +- Updated dependencies [29cedd0] +- Updated dependencies [10f5036] +- Updated dependencies [892bd4f] +- Updated dependencies [32d2a23] +- Updated dependencies [3bd1843] +- Updated dependencies [6a01eef] +- Updated dependencies [9083085] +- Updated dependencies [7beb854] +- Updated dependencies [aa91ba4] +- Updated dependencies [5996db4] +- Updated dependencies [8456549] +- Updated dependencies [4f2de95] +- Updated dependencies [fe1e7e8] +- Updated dependencies [eb17e15] +- Updated dependencies [ef30286] +- Updated dependencies [5720705] +- Updated dependencies [a3419b5] +- Updated dependencies [bc86668] +- Updated dependencies [14917c5] +- Updated dependencies [84872b1] +- Updated dependencies [bbcbf7b] +- Updated dependencies [e11b5d3] +- Updated dependencies [a543f93] +- Updated dependencies [e0898ad] + - @bradygaster/squad-sdk@0.10.0 diff --git a/packages/squad-cli/package.json b/packages/squad-cli/package.json index 1b53b77de..c96cffb14 100644 --- a/packages/squad-cli/package.json +++ b/packages/squad-cli/package.json @@ -1,6 +1,6 @@ { "name": "@bradygaster/squad-cli", - "version": "0.9.6-preview.15", + "version": "0.10.0", "description": "Squad CLI — Command-line interface for the Squad multi-agent runtime", "type": "module", "bin": { @@ -186,7 +186,7 @@ "node": ">=22.5.0" }, "dependencies": { - "@bradygaster/squad-sdk": ">=0.9.6-preview", + "@bradygaster/squad-sdk": ">=0.10.0", "@modelcontextprotocol/sdk": "^1.29.0", "ink": "^6.8.0", "react": "^19.2.4", diff --git a/packages/squad-cli/templates/ralph-reference.md b/packages/squad-cli/templates/ralph-reference.md index 2219d4646..3d8b2b440 100644 --- a/packages/squad-cli/templates/ralph-reference.md +++ b/packages/squad-cli/templates/ralph-reference.md @@ -93,7 +93,7 @@ This runs as a standalone local process (not inside Copilot) that: - Assigns @copilot to `squad:copilot` issues (if auto-assign is enabled) - Runs until Ctrl+C -> **MCP tools in watch mode:** `squad watch` automatically injects `--yolo --additional-mcp-config @.mcp.json` into every Copilot sub-invocation so `squad_state_*` tools are available. This is required because Copilot CLI's non-interactive (`-p`) mode does not auto-load workspace `.mcp.json` due to a folder-trust security gate. If `.mcp.json` is missing, run `squad init` or `squad upgrade` to regenerate it. +**Three layers of Ralph:** | Layer | When | How | |-------|------|-----| diff --git a/packages/squad-cli/templates/skills/fact-checking/SKILL.md b/packages/squad-cli/templates/skills/fact-checking/SKILL.md new file mode 100644 index 000000000..f7f7873e5 --- /dev/null +++ b/packages/squad-cli/templates/skills/fact-checking/SKILL.md @@ -0,0 +1,61 @@ +--- +name: fact-checking +description: Review and validate claims using counter-hypothesis testing. Use when verifying technical content, checking references, validating API endpoints, or performing quality assurance on deliverables. +license: MIT +compatibility: Requires access to external references and APIs +metadata: + author: squad + version: "1.0.0" + domain: quality, verification + confidence: low + last_validated: "2026-03-01" +--- + +# Skill: Fact Checking + +## Context +Codifies the challenger agent review output format and methodology so any agent performing fact-checking or review produces consistent, structured output. + +## Pattern + +### Review Methodology + +For every claim or deliverable under review: +1. Ask: "What evidence supports this? What would disprove it?" +2. Generate counter-hypotheses and test them against available data +3. Verify URLs, package names, API endpoints, and external references actually exist +4. Flag confidence levels: ✅ Verified, ⚠️ Unverified, ❌ Contradicted + +### Review Output Format + +When reviewing another agent's work, use this template: + +``` +### Fact Check — {deliverable name} +**Claims verified:** {count} +**Issues found:** {count} + +| # | Claim | Status | Evidence/Notes | +|---|-------|--------|---------------| +| 1 | {claim} | ✅/⚠️/❌ | {supporting or contradicting evidence} | + +**Counter-hypotheses tested:** +- {alternative explanation + result} + +**Verdict:** {PASS / PASS WITH NOTES / NEEDS REVISION} +``` + +### Confidence Levels + +- ✅ **Verified** — evidence confirms the claim +- ⚠️ **Unverified** — cannot confirm or deny; suggest verification method +- ❌ **Contradicted** — evidence disproves the claim + +### Ceremony Integration + +Auto-trigger this skill before any architecture decision, or when an agent claim contains superlatives or percentage thresholds (e.g., "saves 75%", "always", "never"). The coordinator spawns the challenger agent with: + +``` +Challenger — fact-check {agent}'s claim: "{claim}" +Cite evidence for every verdict. Max 3 investigation cycles. +``` \ No newline at end of file diff --git a/packages/squad-cli/templates/squad.agent.md.template b/packages/squad-cli/templates/squad.agent.md.template index ba0d673c1..9c71cacce 100644 --- a/packages/squad-cli/templates/squad.agent.md.template +++ b/packages/squad-cli/templates/squad.agent.md.template @@ -865,8 +865,6 @@ Do not pause for permission between work items when Ralph is active. **On-demand reference:** Read `.squad/templates/ralph-reference.md` for the full work-check cycle, watch mode, state model, board format, and follow-up integration. -> **Watch mode MCP note:** `squad watch` injects `--yolo --additional-mcp-config @.mcp.json` into every Copilot sub-invocation automatically. Copilot CLI 1.0.59+ does NOT auto-load workspace `.mcp.json` in non-interactive (`-p`) mode due to a folder-trust security gate — this injection is mandatory for `squad_state_*` tools to register. If `.mcp.json` is missing, advise the user to run `squad init` or `squad upgrade`. - ### Connecting to a Repo **On-demand reference:** Read `.squad/templates/issue-lifecycle.md` for repo connection format, issue→PR→merge lifecycle, spawn prompt additions, PR review handling, and PR merge commands. diff --git a/packages/squad-cli/templates/workflow-wiring-appendix-a-code-reviewer.md b/packages/squad-cli/templates/workflow-wiring-appendix-a-code-reviewer.md new file mode 100644 index 000000000..c447f7f9c --- /dev/null +++ b/packages/squad-cli/templates/workflow-wiring-appendix-a-code-reviewer.md @@ -0,0 +1,131 @@ +# Appendix A: Wiring a Code Reviewer — Complete Walkthrough + +> End-to-end example of adding a code reviewer to your squad and wiring their gate so it actually gets enforced. This walkthrough addresses a common failure: a reviewer is on the roster but never reviews a single PR because the gate wasn't wired. + +## The Problem This Solves + +Adding a reviewer to `team.md` gives them an identity. It does NOT: +- Tell the coordinator to route PRs to them +- Prevent PRs from being merged without their approval +- Prevent issues from being closed before review happens + +**What goes wrong without enforcement:** A reviewer can be on the roster as "Reviewer" from day one. Their charter says they review PRs. The routing table says "PR code review → {ReviewerName}." But PRs get merged and issues get closed without them ever being spawned. Why? + +Because the routing table says WHO handles what — it's for incoming requests ("review PR #42"). It does NOT say "after every agent completes work, route their output to {ReviewerName}." The coordinator routes work TO agents, but nothing tells it to route COMPLETED work to a reviewer. The "After Agent Work" flow in `squad.agent.md` says: collect results → present → spawn Scribe. No review step. + +**The fix has three layers:** + +| Layer | What it does | Where it lives | +|-------|-------------|----------------| +| Identity | Reviewer exists and knows how to review | `team.md` roster + `charter.md` | +| Routing | User can explicitly request "review this" | `routing.md` routing table | +| **Enforcement** | Coordinator MUST route every PR to reviewer before merge | `routing.md` Rules section + `issue-lifecycle.md` post-work steps | + +Most squads get layers 1 and 2 right. Layer 3 — enforcement — is what's usually missing. + +## Step-by-Step Walkthrough + +### Step 1: Create the reviewer's identity + +Create `.squad/agents/{name}/charter.md`: + +```markdown +# {Name} — Code Reviewer + +## Identity +- **Name:** {Name} +- **Role:** Code Reviewer +- **Expertise:** Code quality, correctness, test coverage, security, patterns +- **Style:** Thorough, fair, specific. Provides actionable feedback. + +## What I Own +- Reviewing PRs for code quality, correctness, and test coverage +- Identifying bugs, security issues, and design problems +- Providing specific, actionable feedback (not vague suggestions) + +## How I Review +1. Read the PR diff completely +2. Check: does it do what the issue asked for? +3. Check: are there tests? Do they cover the important cases? +4. Check: are there bugs, edge cases, or security issues? +5. Check: does it follow project patterns and conventions? +6. Verdict: APPROVE or REJECT with specific feedback + +## Boundaries +**I handle:** Code review, PR review, quality gates +**I don't handle:** Implementation, design, research, documentation + +## On REJECT +I provide specific feedback: what's wrong, why, and what to do instead. +The original author fixes their work. I re-review after fixes. +``` + +Create `.squad/agents/{name}/history.md` seeded with project context. + +### Step 2: Add to team.md roster + +```markdown +| 👑 {Name} | Code Reviewer | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing table entry + +In `routing.md` → routing table: + +```markdown +| PR code review | 👑 {Name} | — | "Review PR #42", code quality, finding reports | +``` + +**⚠️ This is necessary but NOT sufficient.** This only handles explicit review requests. It does NOT enforce automatic review of every PR. + +### Step 4: Add enforcement rule (THIS IS THE CRITICAL STEP) + +In `routing.md` → `## Rules` section, add a numbered rule: + +```markdown +N. **{Name} PR Gate** — every PR created by any agent MUST be reviewed by {Name} + before merge. The coordinator spawns {Name} (sync) with the PR diff after + the author pushes and creates the PR. On REJECT, the original author addresses + feedback. On APPROVE, the coordinator merges via `gh pr merge`. No PR merges + without {Name}'s approval. +``` + +**Why this works when the routing table alone didn't:** The routing table is for matching incoming work to agents. Rules are behavioral constraints the coordinator must follow AFTER work completes. The rule says "after a PR exists, you MUST do X before proceeding." The routing table says "if someone asks for a review, route to X." + +### Step 5: Wire into issue-lifecycle.md + +In `.squad/templates/issue-lifecycle.md`, the "Coordinator Post-Work Steps" section should reference your reviewer by name: + +```markdown +4. **Route to reviewer.** Spawn {Name} (sync) with the PR diff for code review. +``` + +This is the operational detail — the step-by-step instructions the coordinator follows after an agent completes issue work. The routing rule (Step 4) is the mandate; the lifecycle template is the procedure. + +### Step 6: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 7: Verify + +Ask yourself these questions: + +- [ ] If a clean session coordinator reads `routing.md` Rules, will it know to route PRs to this reviewer? → Check rule N exists. +- [ ] If an agent completes work and pushes a PR, does the coordinator's post-work flow include a review step? → Check `issue-lifecycle.md` step 4. +- [ ] Can the coordinator merge a PR without the reviewer's approval? → The rule should say "No PR merges without {Name}'s approval." +- [ ] Can the coordinator close an issue without a merged PR? → Check the issue closure rule exists. + +If any answer is wrong, you have a gap. + +## What Each File Controls (Summary) + +| File | What it contributes to the reviewer gate | +|------|----------------------------------------| +| `charter.md` | WHO the reviewer is and HOW they review | +| `team.md` | That the reviewer EXISTS on the team | +| `routing.md` routing table | That explicit review requests go to this reviewer | +| `routing.md` Rules section | That the coordinator MUST route EVERY PR to this reviewer (enforcement) | +| `issue-lifecycle.md` | The step-by-step procedure for the post-work review flow | +| `casting/registry.json` | Persistent name tracking | + +**Remove any one of these and the gate has a hole.** The most commonly missed piece is the Rules section entry (Step 4). diff --git a/packages/squad-cli/templates/workflow-wiring-appendix-b-documenter.md b/packages/squad-cli/templates/workflow-wiring-appendix-b-documenter.md new file mode 100644 index 000000000..fb8cd26aa --- /dev/null +++ b/packages/squad-cli/templates/workflow-wiring-appendix-b-documenter.md @@ -0,0 +1,140 @@ +# Appendix B: Wiring a Documenter/Librarian — Complete Walkthrough + +> End-to-end example of adding a documenter role that ensures significant changes are documented. This is a FOLLOW-UP TRIGGER pattern — not a gate (which blocks), but an automatic downstream task that fires after work completes. + +## The Problem This Solves + +Your project has agents building features, fixing bugs, and writing tools. But nobody documents what was built, how to use it, or what changed. Documentation happens only when someone explicitly asks — and by then, the context is lost. + +A documenter/librarian role solves this by automatically evaluating whether completed work needs documentation and producing it if so. + +## Gate vs Follow-Up Trigger + +| Pattern | Blocks work? | When it runs | Example | +|---------|-------------|-------------|---------| +| **Gate** (Appendix A) | Yes — work cannot proceed without approval | Before merge | Code reviewer must approve PR | +| **Follow-up trigger** | No — work proceeds, documentation happens in parallel | After merge | Documenter evaluates if docs are needed | + +A documenter is typically a follow-up trigger, not a gate. You don't want documentation review to block a hotfix from merging. But you DO want documentation to happen automatically after significant changes. + +## Step-by-Step Walkthrough + +### Step 1: Create the documenter's identity + +Create `.squad/agents/{name}/charter.md`: + +```markdown +# {Name} — Documenter + +## Identity +- **Name:** {Name} +- **Role:** Documenter / Librarian +- **Expertise:** Documentation, guides, READMEs, changelogs, knowledge management +- **Style:** Clear, thorough, user-focused. Makes complex things understandable. + +## What I Own +- Evaluating whether completed work needs documentation +- Writing/updating READMEs, guides, and runbooks +- Maintaining a docs index so nothing gets lost +- Summarizing design decisions and architectural changes + +## How I Work +1. Read the PR diff or agent output +2. Assess: does this change user-facing behavior? Add a new feature? Change configuration? +3. If yes: write or update the relevant documentation +4. If no: report "no docs needed" with brief justification + +## Boundaries +**I handle:** Documentation, guides, READMEs, summaries, knowledge management +**I don't handle:** Code implementation, code review, research, operations +``` + +Create `.squad/agents/{name}/history.md` seeded with project context. + +### Step 2: Add to team.md roster + +```markdown +| 📝 {Name} | Documenter | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing table entry + +In `routing.md` → routing table: + +```markdown +| Documentation, reports, summaries | 📝 {Name} | `docs/` | "Write docs for X", "Summarize this", guides, READMEs | +``` + +### Step 4: Add follow-up trigger rule + +In `routing.md` → `## Rules` section, add a numbered rule: + +```markdown +N. **Documentation follow-up** — after any PR is merged that adds or modifies + user-facing features, scripts, tools, or configuration, the coordinator + spawns {Name} (background) to evaluate whether documentation is needed. + {Name} reads the merged PR diff and either writes/updates docs or reports + "no docs needed." This is a follow-up, not a gate — it does not block + the merge. +``` + +**Why a rule and not a ceremony:** Ceremonies are structured multi-participant meetings. This is a single-agent follow-up task. A routing rule is simpler and more appropriate. + +**Why background, not sync:** Documentation doesn't block other work. The documenter runs in parallel with whatever comes next. + +### Step 5: Wire into the coordinator's post-merge flow + +This is the trickiest part. The coordinator's After Agent Work flow doesn't currently have a "post-merge" hook. You wire this through the issue-lifecycle template. + +In `.squad/templates/issue-lifecycle.md`, after the merge step, add: + +```markdown +8. **Documentation follow-up.** After merge, check routing.md Rules for + documentation follow-up rule. If present, spawn the documenter (background) + with the merged PR diff to evaluate whether docs are needed. +``` + +Alternatively, you can wire this as an `after` ceremony in `ceremonies.md`: + +```yaml +- name: "Documentation Check" + when: "after" + condition: "PR merged that adds features, scripts, tools, or config changes" + facilitator: "{DocumenterName}" + participants: ["{DocumenterName}"] + output: "Docs written/updated, or 'no docs needed' with justification" +``` + +### Step 6: Worktree for doc changes + +If the documenter produces files, they need a worktree — docs are files too. The coordinator should: +1. Create a worktree for the doc update (e.g., `squad/{issue}-docs`) +2. The documenter commits and pushes +3. A PR is created for the docs +4. The docs PR goes through the normal review flow (including the code reviewer if you have one) + +This means doc changes also get reviewed. The documenter is not exempt from the review gate. + +### Step 7: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 8: Verify + +- [ ] After a feature PR merges, does the coordinator spawn the documenter? → Check the routing rule exists. +- [ ] Does the documenter get a worktree for their work? → Check the worktree rule covers docs. +- [ ] Do doc changes go through the review gate? → They should — docs are files, files need PRs, PRs need review. +- [ ] Is the follow-up non-blocking? → The documenter should be background, not sync. + +## What Each File Controls (Summary) + +| File | What it contributes | +|------|-------------------| +| `charter.md` | WHO the documenter is and HOW they evaluate | +| `team.md` | That the documenter EXISTS | +| `routing.md` routing table | That explicit doc requests go to this member | +| `routing.md` Rules section | That the coordinator MUST spawn docs evaluation after merges (enforcement) | +| `issue-lifecycle.md` or `ceremonies.md` | The procedural hook: when exactly the follow-up fires | +| `casting/registry.json` | Persistent name tracking | + +**The most commonly missed piece:** The Rules section entry (Step 4). Without it, the documenter only runs when someone explicitly says "write docs for X." The whole point is that it runs automatically. diff --git a/packages/squad-cli/templates/workflow-wiring-guide.md b/packages/squad-cli/templates/workflow-wiring-guide.md new file mode 100644 index 000000000..853a13d0a --- /dev/null +++ b/packages/squad-cli/templates/workflow-wiring-guide.md @@ -0,0 +1,276 @@ +# Squad Workflow Wiring Guide + +> How to wire up new team members, reviewer gates, and custom workflows so they actually get enforced by the coordinator — even in a clean session with no prior memory. + +## Why This Guide Exists + +The Squad framework (`squad.agent.md`) provides generic orchestration primitives. **It does not prescribe a specific workflow.** Your project's workflow — whether that's "all code goes through PRs and reviews" or "just commit to main" — must be wired into project-level configuration files. + +If a workflow rule exists only in someone's memory, in a chat transcript, or in `decisions.md` but NOT in a configuration file the coordinator reads at decision time — **it will not be followed in a clean session.** + +### Why Existing Patterns Aren't Enough + +The Squad framework already has concepts for routing tables, reviewer roles, and ceremonies. But having these concepts does NOT mean they work automatically: + +- **Adding a reviewer to the roster ≠ enforcing reviews.** A reviewer can be on the roster with "Reviewer" as their role and never review a single PR — because no RULE in `routing.md` tells the coordinator to route PRs to them. The roster says WHO exists. Rules say WHAT they enforce. + +- **Capturing a decision ≠ enforcing it.** `decisions.md` may contain "every change must go through a PR" and "only {ReviewerName} closes PRs." These can get buried in a large file that the coordinator reads for context but doesn't treat as enforcement rules. A decision is a historical record. A routing rule is an enforceable constraint. + +- **Describing a lifecycle ≠ wiring it.** `squad.agent.md` describes issue→branch→PR→review→merge. But if the After Agent Work section (the flow the coordinator actually follows after every agent completes) has no push/PR/review step, the lifecycle is described conceptually but never connected to the coordinator's actual decision flow. + +**The pattern that works:** A numbered rule in `routing.md` → Rules section. The coordinator reads this section, treats each rule as a constraint, and follows them. If your workflow isn't a numbered rule, it's a suggestion. + +--- + +## Configuration Surface Area + +The coordinator reads these files to decide how to behave. If your workflow isn't encoded in one of these, it doesn't exist. + +| File | What It Controls | Read When | +|------|-----------------|-----------| +| `routing.md` | WHO handles what, behavioral RULES, reviewer GATES | Every session start, before every routing decision | +| `ceremonies.md` | Auto-triggered ceremonies (before/after work batches) | Before spawning work batches, after completion | +| `templates/issue-lifecycle.md` | Git workflow: push, PR, review, merge, issue closure | When spawning agents for issue-linked work | +| Agent `charter.md` | Per-agent identity, boundaries, behavior | Inlined into every spawn prompt | +| `team.md` | Roster, member capabilities | Session start | +| `decisions.md` | Captured decisions and directives | Read by agents at spawn time | + +### How They Interact + +``` +User request arrives + → Coordinator reads routing.md (WHO handles this?) + → Coordinator checks ceremonies.md (any auto-triggered "before" ceremony?) + → Coordinator reads agent charter.md (inline into spawn prompt) + → If issue-linked: coordinator reads issue-lifecycle.md (add ISSUE CONTEXT to spawn prompt) + → Agent works + → Coordinator follows After Agent Work flow + → Coordinator checks ceremonies.md (any auto-triggered "after" ceremony?) + → Coordinator checks routing.md Rules section (any post-work rules to enforce?) +``` + +**The critical insight:** `routing.md` Rules section and `ceremonies.md` are the two enforcement mechanisms. If a rule isn't in one of these, the coordinator has no way to know about it. + +--- + +## How to Wire Up a New Team Member + +### Step 1: Create the member (files) + +``` +.squad/agents/{name}/ + charter.md ← Identity, role, boundaries, what they own + history.md ← Seeded with project context from team.md +``` + +### Step 2: Add to roster (`team.md`) + +Add a row to the `## Members` table: +``` +| {emoji} {Name} | {Role} | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing entry (`routing.md`) + +Add a row to the routing table: +``` +| {Work Type} | {emoji} {Name} | {Output Location} | {Examples} | +``` + +### Step 4: Add issue routing (if applicable) + +Add to the Issue Routing table in `routing.md`: +``` +| squad:{name} | {Description of work} | {emoji} {Name} | +``` + +### Step 5: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 6: Wire any gates (if this member is a reviewer/gate) + +**This is the step most people miss.** If the new member should review or gate other members' work, you need to wire enforcement. See "How to Wire Up a Reviewer Gate" below. + +--- + +## How to Wire Up a Reviewer Gate + +A reviewer gate means: "Agent X must review Agent Y's output before it proceeds." The framework supports this but does NOT automatically enforce it. You must wire it. + +### Option A: Routing Rule (recommended for simple gates) + +Add to `routing.md` → `## Rules` section: + +```markdown +N. **{GateName} Gate** — Every {output type} from {Author} MUST be reviewed by {ReviewerName} before {next step}. The coordinator routes {Author}'s output to {ReviewerName} (sync spawn), collects the verdict, and only proceeds if approved. On rejection, {Author} revises based on {ReviewerName}'s feedback. +``` + +**Example — reviewer for all PRs:** +```markdown +9. **{ReviewerName} PR Gate** — Every PR created by any agent MUST be reviewed by {ReviewerName} before merge. The coordinator spawns {ReviewerName} (sync) with the PR diff, collects APPROVE/REJECT verdict. On rejection, the original author addresses feedback. +``` + +**Example — design review gate:** +```markdown +10. **{DesignReviewer} Design Gate** — Every design doc produced by the architect MUST be reviewed by {DesignReviewer} before implementation begins. {DesignReviewer} always rejects the first draft on concept/approach. Implementation is BLOCKED until {DesignReviewer} approves. +``` + +**Why this works:** The coordinator reads the Rules section before and after every work batch. Rules are behavioral constraints the coordinator must follow. + +### Option B: Ceremony (recommended for multi-participant gates) + +Add to `ceremonies.md` using the Markdown table format the file uses: + +```markdown +## Design Review + +| Field | Value | +|-------|-------| +| **Trigger** | auto | +| **When** | before | +| **Condition** | task involves implementing a design doc | +| **Facilitator** | {DesignReviewer} | +| **Participants** | Architect, {DesignReviewer} | +| **Time budget** | focused | +| **Enabled** | ✅ yes | + +**Agenda:** +1. Read the design doc +2. Challenge the premise and approach +3. Demand alternatives and evidence +4. Verdict: APPROVE or REJECT +``` + +**Why this works:** The coordinator checks ceremonies.md for `before` ceremonies whose condition matches the current task. If matched, the ceremony runs before work begins. + +### Option A vs Option B + +| Use Case | Use Routing Rule | Use Ceremony | +|----------|-----------------|--------------| +| Simple 1-on-1 review (reviewer → author) | ✅ | Overkill | +| Multi-participant alignment (3+ agents) | Too simple | ✅ | +| Needs structured facilitation | No | ✅ | +| Must run automatically before specific work | Either works | ✅ | +| One-line behavioral constraint | ✅ | Overkill | + +--- + +## How to Wire Up an Issue Lifecycle (Git Workflow) + +This is where you define what happens after an agent completes work on a GitHub issue. The framework references `.squad/templates/issue-lifecycle.md` but does NOT create it — you must create it yourself. + +> **⚠️ This file is required if your project uses GitHub Issues Mode.** Without it, the coordinator has no post-work steps for push/PR/review and will treat agent commit as "done." + +See `.squad/templates/issue-lifecycle.md` for the full template if your project already has one. If not, create it following the pattern below. + +### Step 1: Create `templates/issue-lifecycle.md` + +Create `.squad/templates/issue-lifecycle.md` with your project's git workflow. At minimum it should include: + +- An ISSUE CONTEXT block template (for spawn prompts) +- Coordinator post-work steps (verify push → verify PR → route to reviewer → merge on approval) +- Issue closure rules (PR merge auto-close vs manual close) +- Worktree requirements (if applicable) + +### Step 2: Add enforcement rules to `routing.md` + +Add numbered rules to the `## Rules` section that reference the lifecycle: + +```markdown +N. **Issue lifecycle enforcement** — all issue-linked work follows the lifecycle + in `.squad/templates/issue-lifecycle.md`. The coordinator adds the ISSUE CONTEXT + block to spawn prompts and follows the post-work steps (verify push → verify PR + → route to reviewer → merge on approval). Read `issue-lifecycle.md` before + spawning any agent for issue work. + +N+1. **{ReviewerName} PR Gate** — every PR created by any agent MUST be reviewed + by {ReviewerName} before merge. The coordinator spawns {ReviewerName} (sync) + with the PR diff. On REJECT, the original author addresses feedback. On APPROVE, + the coordinator merges. No PR merges without {ReviewerName}'s approval. + +N+2. **Issue closure restriction** — issues that produced files (code, docs, scripts, + designs, tests) close ONLY via PR merge auto-close ("Closes #N" in PR body). + Never use `gh issue close` for file-producing work. Exception: tracking/strategic + issues and superseded issues may be closed with a comment. + +N+3. **Worktree for all file-producing work** — every task that creates or modifies + files (including documentation) requires a worktree. Exceptions: read-only queries, + Scribe (.squad/ state), pure analysis producing no files. +``` + +### Step 3: Verify your wiring + +After creating both files, run the verification checklist (below) to confirm a clean session coordinator would follow the lifecycle. + +--- + +## How to Wire Up a Custom Workflow Step + +If you need something that isn't a reviewer gate or issue lifecycle — for example, "always run tests before pushing" or "docs must be reviewed by the author before merge" — here's where to put it: + +### If it's a behavioral rule the coordinator should always follow: +→ Add to `routing.md` → `## Rules` section + +### If it should trigger automatically before/after specific work: +→ Add to `ceremonies.md` as a `before` or `after` ceremony + +### If it's something agents should do as part of their work: +→ Add to the agent's `charter.md` under a new section + +### If it's something that applies only to issue-linked work: +→ Add to `templates/issue-lifecycle.md` + +### If it's a team-wide constraint that should be visible to all agents: +→ Capture as a decision in `decisions.md` (via directive or decision inbox) + +--- + +## Verification Checklist + +After wiring any new member, gate, or workflow, verify: + +- [ ] **Clean session test:** Start a new session (no memory). Give a task. Does the coordinator follow the new rule? +- [ ] **File completeness:** Is the rule/gate/workflow encoded in a file the coordinator reads? (routing.md, ceremonies.md, issue-lifecycle.md, charter.md) +- [ ] **No verbal-only rules:** Is there anything the coordinator should do that's only in chat history or your memory? If yes, it will be lost on session restart. +- [ ] **Gate enforcement:** If you added a reviewer gate, does the routing.md Rules section or ceremonies.md explicitly say the coordinator must route to the reviewer? "Having a reviewer on the roster" is not the same as "enforcing that they review." +- [ ] **Issue lifecycle:** If your project uses PRs, does `templates/issue-lifecycle.md` exist? Does routing.md reference it? + +--- + +## Common Mistakes + +1. **Adding a reviewer to the roster but not wiring a gate.** Having a reviewer on the team doesn't mean they review anything. You must add a rule in routing.md that says "route PRs to {ReviewerName}." + +2. **Closing issues via `gh issue close` instead of PR merge.** If your project uses PRs, issue closure should happen via "Closes #N" in the PR body. Wire this in issue-lifecycle.md. + +3. **Writing docs/scripts directly on main.** If your project requires branches for all changes, the worktree gate must apply to ALL file-producing work — including docs. Make this explicit in routing.md Rules. + +4. **Assuming the coordinator remembers verbal instructions.** Each session starts fresh. If you told the coordinator "always use opus" in session 1, session 2 won't know unless it's in decisions.md or routing.md. + +5. **Not creating `issue-lifecycle.md`.** The framework references it but doesn't create it. If your project uses GitHub Issues Mode, create this template. + +6. **Capturing a decision but never encoding it as a rule.** `decisions.md` is a historical record. The coordinator reads it for context but doesn't treat entries as enforceable constraints. If a decision should be enforced, it must become a numbered rule in `routing.md` Rules section. + +--- + +## Decisions Audit + +Periodically scan `decisions.md` for directives that should be routing rules but aren't: + +1. Search for phrases like "always", "never", "must", "every", "required" +2. For each match, ask: "Is this enforced by a numbered rule in routing.md?" +3. If no → either add a rule, or accept that it's advisory-only +4. If yes → verify the rule text matches the decision + +This prevents `decisions.md` from becoming a graveyard of good intentions that the coordinator reads but doesn't act on. + +--- + +## Appendices + +For detailed end-to-end walkthroughs of specific wiring scenarios, see: + +- **[Appendix A: Wiring a Code Reviewer](workflow-wiring-appendix-a-code-reviewer.md)** — Full walkthrough of adding a code reviewer member and wiring their gate so it actually gets enforced. Includes every file that needs modification with exact content. + +- **[Appendix B: Wiring a Documenter/Librarian](workflow-wiring-appendix-b-documenter.md)** — Full walkthrough of adding a documenter role that ensures all significant changes are documented. Shows a follow-up trigger pattern rather than a gate pattern. diff --git a/packages/squad-cli/templates/workflows/squad-heartbeat.yml b/packages/squad-cli/templates/workflows/squad-heartbeat.yml index 1b75fda3e..5494296fd 100644 --- a/packages/squad-cli/templates/workflows/squad-heartbeat.yml +++ b/packages/squad-cli/templates/workflows/squad-heartbeat.yml @@ -1,167 +1,167 @@ -name: Squad Heartbeat (Ralph) -# ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all: -# - templates/workflows/squad-heartbeat.yml (source template) -# - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package) -# - .squad/templates/workflows/squad-heartbeat.yml (installed template) -# - .github/workflows/squad-heartbeat.yml (active workflow) -# Run 'squad upgrade' to sync installed copies from source templates. - -on: - # React to completed work or new squad work - issues: - types: [closed, labeled] - pull_request: - types: [closed] - - # Manual trigger - workflow_dispatch: - -permissions: - issues: write - contents: read - pull-requests: read - -jobs: - heartbeat: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Check triage script - id: check-script - run: | - if [ -f ".squad/templates/ralph-triage.js" ]; then - echo "has_script=true" >> $GITHUB_OUTPUT - else - echo "has_script=false" >> $GITHUB_OUTPUT - echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install" - fi - - - name: Ralph — Smart triage - if: steps.check-script.outputs.has_script == 'true' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node .squad/templates/ralph-triage.js \ - --squad-dir .squad \ - --output triage-results.json - - - name: Ralph — Apply triage decisions - if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != '' - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const path = 'triage-results.json'; - if (!fs.existsSync(path)) { - core.info('No triage results — board is clear'); - return; - } - - const results = JSON.parse(fs.readFileSync(path, 'utf8')); - if (results.length === 0) { - core.info('📋 Board is clear — Ralph found no untriaged issues'); - return; - } - - for (const decision of results) { - try { - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: decision.issueNumber, - labels: [decision.label] - }); - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: decision.issueNumber, - body: [ - '### 🔄 Ralph — Auto-Triage', - '', - `**Assigned to:** ${decision.assignTo}`, - `**Reason:** ${decision.reason}`, - `**Source:** ${decision.source}`, - '', - '> Ralph auto-triaged this issue using routing rules.', - '> To reassign, swap the `squad:*` label.' - ].join('\n') - }); - - core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`); - } catch (e) { - core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`); - } - } - - core.info(`🔄 Ralph triaged ${results.length} issue(s)`); - - # Copilot auto-assign step (uses PAT if available) - - name: Ralph — Assign @copilot issues - if: success() - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const fs = require('fs'); - - let teamFile = '.squad/team.md'; - if (!fs.existsSync(teamFile)) { - teamFile = '.ai-team/team.md'; - } - if (!fs.existsSync(teamFile)) return; - - const content = fs.readFileSync(teamFile, 'utf8'); - - // Check if @copilot is on the team with auto-assign - const hasCopilot = content.includes('🤖 Coding Agent') || content.includes('@copilot'); - const autoAssign = content.includes(''); - if (!hasCopilot || !autoAssign) return; - - // Find issues labeled squad:copilot with no assignee - try { - const { data: copilotIssues } = await github.rest.issues.listForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - labels: 'squad:copilot', - state: 'open', - per_page: 5 - }); - - const unassigned = copilotIssues.filter(i => - !i.assignees || i.assignees.length === 0 - ); - - if (unassigned.length === 0) { - core.info('No unassigned squad:copilot issues'); - return; - } - - // Get repo default branch - const { data: repoData } = await github.rest.repos.get({ - owner: context.repo.owner, - repo: context.repo.repo - }); - - for (const issue of unassigned) { - try { - await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue.number, - assignees: ['copilot-swe-agent[bot]'], - agent_assignment: { - target_repo: `${context.repo.owner}/${context.repo.repo}`, - base_branch: repoData.default_branch, - custom_instructions: `Read .squad/team.md (or .ai-team/team.md) for team context and .squad/routing.md (or .ai-team/routing.md) for routing rules.` - } - }); - core.info(`Assigned copilot-swe-agent[bot] to #${issue.number}`); - } catch (e) { - core.warning(`Failed to assign @copilot to #${issue.number}: ${e.message}`); - } - } - } catch (e) { - core.info(`No squad:copilot label found or error: ${e.message}`); - } +name: Squad Heartbeat (Ralph) +# ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all: +# - templates/workflows/squad-heartbeat.yml (source template) +# - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package) +# - .squad/templates/workflows/squad-heartbeat.yml (installed template) +# - .github/workflows/squad-heartbeat.yml (active workflow) +# Run 'squad upgrade' to sync installed copies from source templates. + +on: + # React to completed work or new squad work + issues: + types: [closed, labeled] + pull_request: + types: [closed] + + # Manual trigger + workflow_dispatch: + +permissions: + issues: write + contents: read + pull-requests: read + +jobs: + heartbeat: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check triage script + id: check-script + run: | + if [ -f ".squad/templates/ralph-triage.js" ]; then + echo "has_script=true" >> $GITHUB_OUTPUT + else + echo "has_script=false" >> $GITHUB_OUTPUT + echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install" + fi + + - name: Ralph — Smart triage + if: steps.check-script.outputs.has_script == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + node .squad/templates/ralph-triage.js \ + --squad-dir .squad \ + --output triage-results.json + + - name: Ralph — Apply triage decisions + if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != '' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = 'triage-results.json'; + if (!fs.existsSync(path)) { + core.info('No triage results — board is clear'); + return; + } + + const results = JSON.parse(fs.readFileSync(path, 'utf8')); + if (results.length === 0) { + core.info('📋 Board is clear — Ralph found no untriaged issues'); + return; + } + + for (const decision of results) { + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: decision.issueNumber, + labels: [decision.label] + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: decision.issueNumber, + body: [ + '### 🔄 Ralph — Auto-Triage', + '', + `**Assigned to:** ${decision.assignTo}`, + `**Reason:** ${decision.reason}`, + `**Source:** ${decision.source}`, + '', + '> Ralph auto-triaged this issue using routing rules.', + '> To reassign, swap the `squad:*` label.' + ].join('\n') + }); + + core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`); + } catch (e) { + core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`); + } + } + + core.info(`🔄 Ralph triaged ${results.length} issue(s)`); + + # Copilot auto-assign step (uses PAT if available) + - name: Ralph — Assign @copilot issues + if: success() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + + let teamFile = '.squad/team.md'; + if (!fs.existsSync(teamFile)) { + teamFile = '.ai-team/team.md'; + } + if (!fs.existsSync(teamFile)) return; + + const content = fs.readFileSync(teamFile, 'utf8'); + + // Check if @copilot is on the team with auto-assign + const hasCopilot = content.includes('🤖 Coding Agent') || content.includes('@copilot'); + const autoAssign = content.includes(''); + if (!hasCopilot || !autoAssign) return; + + // Find issues labeled squad:copilot with no assignee + try { + const { data: copilotIssues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + labels: 'squad:copilot', + state: 'open', + per_page: 5 + }); + + const unassigned = copilotIssues.filter(i => + !i.assignees || i.assignees.length === 0 + ); + + if (unassigned.length === 0) { + core.info('No unassigned squad:copilot issues'); + return; + } + + // Get repo default branch + const { data: repoData } = await github.rest.repos.get({ + owner: context.repo.owner, + repo: context.repo.repo + }); + + for (const issue of unassigned) { + try { + await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + assignees: ['copilot-swe-agent[bot]'], + agent_assignment: { + target_repo: `${context.repo.owner}/${context.repo.repo}`, + base_branch: repoData.default_branch, + custom_instructions: `Read .squad/team.md (or .ai-team/team.md) for team context and .squad/routing.md (or .ai-team/routing.md) for routing rules.` + } + }); + core.info(`Assigned copilot-swe-agent[bot] to #${issue.number}`); + } catch (e) { + core.warning(`Failed to assign @copilot to #${issue.number}: ${e.message}`); + } + } + } catch (e) { + core.info(`No squad:copilot label found or error: ${e.message}`); + } diff --git a/packages/squad-sdk/CHANGELOG.md b/packages/squad-sdk/CHANGELOG.md new file mode 100644 index 000000000..7f9c7f309 --- /dev/null +++ b/packages/squad-sdk/CHANGELOG.md @@ -0,0 +1,344 @@ +# @bradygaster/squad-sdk + +## 0.10.0 + +### Minor Changes + +- a1fcdb8: Add rework rate OTEL metrics (#265) — tracks PR revision patterns as the emerging 5th DORA metric +- 6a72634: Add routing.md to squad export/import functionality + + The routing.md file is now included when exporting and importing Squad configurations. + This preserves the full routing context (tables, comments, principles) alongside the + structured routing rules that were already exported. + +- ba8d8f7: Add SkillScriptLoader, handler types, and applySkillHandlers for executable skill handler scripts +- 1446050: ADO configurable work item types, area paths, and iteration support (#240) + + - Add `getAvailableWorkItemTypes(org, project)` for process template introspection + - Add `validateWorkItemType(org, project, typeName)` for pre-creation validation + - Add `WorkItemTypeInfo` interface for type metadata + - Enhance `AzureDevOpsAdapter` with instance-level `getAvailableWorkItemTypes()` and `validateWorkItemType()` methods + - Support optional `validateType` flag in `createWorkItem()` to check type before creation + - Enhance `squad init` to introspect available work item types and store `_availableTypes` hint in `.squad/config.json` + - Support `adoConfig` in `InitOptions` for explicit work item type, area path, and iteration path during init + - Graceful fallback to default types (User Story, Bug, Task) when az CLI is unavailable + +- 7f86e0e: feat: Cooperative rate limiting with predictive circuit breaker + + Added cooperative rate limiting patterns for multi-agent deployments: + + - Traffic Light, Predictive Circuit Breaker, Priority Retry Windows + - Cooperative Token Pool for shared quota management + + Closes #515 + +- 5826555: Cross-squad orchestration — discovery, delegation, and manifest (#316). Adds manifest schema, `squad discover` / `squad delegate` commands, and runtime module for coordinating work across multiple Squad instances. +- dafc495: Add dual-mode deployment support for capabilities routing. + + New features: + + - `SQUAD_POD_ID` env var for pod-specific capability manifests + - `SQUAD_DEPLOYMENT_MODE` env var (`agent-per-node` | `squad-per-pod`) + - Pod-specific manifest loading: `.squad/machine-capabilities-{podId}.json` + - Fallback chain: pod-specific → shared → user-home → null (opt-in) + - New exports: `getDeploymentMode()`, `getPodId()`, `DeploymentMode` type + +- 9c3156a: feat: add error-recovery skill for standard agent failure recovery patterns +- 37def62: Add external state storage — move .squad/ out of the working tree (#792) + + - New `stateLocation: 'external'` option in `.squad/config.json` + - `resolveExternalStateDir()` resolves state under the platform-specific global Squad directory (`resolveGlobalSquadPath()`) + - `deriveProjectKey()` generates a stable key from the repo path (cross-platform) + - `resolveSquadPaths()` honors external state location + - `squad externalize` moves state out, `squad internalize` moves it back + - State survives branch switches, invisible to `git status`, never pollutes PRs + - Thin `.squad/config.json` marker stays in repo (gitignored) + - Path traversal protection on projectKey + - 12 new tests + +- 9a53769: Add fact-checker as a built-in agent role (#789) + + - New `fact-checker` role in the engineering role catalog (emoji: 🔍, category: quality) + - Charter template at `templates/fact-checker-charter.md` with verification methodology + - Added to `AGENT_TEMPLATES` for init scaffolding + - Template manifest entry for init/upgrade distribution + - Routing patterns: fact-check, verify, validate, audit, double-check, hallucination, devil's advocate + +- 7f9a878: feat(sdk): git-notes + orphan-branch state backends for .squad/ + + Adds git-native state storage backends as alternatives to the local (disk) + approach: + + - **orphan-branch** (`squad-state`): Dedicated orphan branch with no common + ancestor. State files never appear in main. + - **two-layer** (notes + orphan): Git notes as best-effort commit annotations + plus orphan branch for durable state. Recommended for teams. + + Configure via `.squad/config.json`: `{ "stateBackend": "two-layer" }` or + the `--state-backend` CLI flag. + +- 87e9381: feat: add iterative-retrieval skill for structured max-3-cycle agent spawning +- 8d49066: feat: Machine capability discovery and `needs:*` label-based issue routing + + Added capability filtering to Ralph's watch command. Issues with `needs:*` labels + (e.g., `needs:gpu`, `needs:browser`) are only processed by Ralph instances whose + machine has those capabilities declared in `machine-capabilities.json`. + + This enables multi-machine Squad deployments where different machines handle + different types of work based on their available tooling. + + Closes #514 + +- 900d2e4: Add `squad init --mcp-frontmatter` to write MCP server config into the Squad agent frontmatter instead of `.copilot/mcp-config.json` for compatible agent harnesses. +- a9c06b0: feat: add notification-routing skill for pub-sub channel routing +- 32d2a23: Enable persistent Ralph — heartbeat cron + healthCheck timer + + - Enable cron schedule in squad-heartbeat.yml (all 5 sync locations) + - Enable RalphMonitor healthCheck timer (previously commented out pre-migration) + - Add platform detection tests for getRalphScanCommands (GitHub/ADO/Planner) + - Add healthCheck timer tests with fake timers (start/stop/interval/stale detection) + +- 6a01eef: Add Rai as Squad's third built-in agent — a Responsible AI (RAI) reviewer + + - Rai is always on the roster (like Scribe and Ralph), exempt from casting + - Traffic light verdict model: 🟢 Green (proceed), 🟡 Yellow (advisory), 🔴 Red (blocking) + - Background mode by default — only blocks on critical RAI violations + - Phase 1 high-signal checks: credentials, injection, harmful content, bias, PII + - New templates: Rai-charter.md, rai-policy.md + - New `.squad/rai/` directory with policy.md and audit-trail.md + - Tiered opt-out model (cannot disable critical checks) + +- 9083085: feat: add reflect skill for in-session learning capture and mistake prevention +- 7beb854: Add `--repo` and `--branch` flags to `squad export` and `squad import` commands, enabling users to push/pull Squad configuration directly to/from a GitHub repository via the GitHub Contents API. +- 5996db4: Add `.squad/.scratch/` directory for organized temp file management (#790) + + - `scratchDir()` — resolve and optionally create the scratch directory + - `scratchFile()` — create named temp files inside `.scratch/` + - Init scaffolds `.squad/.scratch/` and adds it to `.gitignore` + - Agents and CLI should use these utilities instead of writing temp files to repo root + +- fe1e7e8: Squad coordinator now scans all 5 project skill directories: Copilot CLI's 3 + official project paths — `.github/skills/`, `.claude/skills/`, `.agents/skills/` + (per https://docs.github.com/en/copilot/how-tos/copilot-cli/customize-copilot/add-skills) + — plus Squad's existing conventions `.squad/skills/` and `.copilot/skills/`. + Precedence: `.squad/skills/` > `.copilot/skills/` > `.github/skills/` > + `.claude/skills/` > `.agents/skills/` (dedup by directory name). Personal + paths (`~/.copilot/skills/`, `~/.agents/skills/`) are deliberately excluded + from explicit routing — Copilot CLI injects them ambiently. This closes a gap + where skills placed in `.github/skills/` (a common location alongside other + `.github/` tooling) were loaded by Copilot CLI but invisible to Squad's + coordinator-attached skill-aware routing. +- ef30286: feat: add SQUAD_HOME env var and preset system + + - Add `SQUAD_HOME` environment variable support for a roaming squad root directory + - Add preset system for reusable agent configurations (list, show, apply, init) + - Ship a default built-in preset with 5 agents (lead, reviewer, devrel, security, docs) + - Add `squad preset` CLI command with list, show, apply, and init subcommands + - Resolves #1038 + +- 5720705: Generic, provider-agnostic scheduler for Squad (#296) — unified schedule.json manifest with LocalPolling and GitHubActions provider adapters, CLI commands (list, run, init, status), schema validation, and cron/interval trigger evaluation. +- bc86668: Add delete() and append() to StateBackend interface; add resolveSquadState() entry point; add StateBackendStorageAdapter; add git-notes agent protocol templates + + - Add `delete()` and `append()` methods to the `StateBackend` interface + - Implement delete/append for all three backends (local, orphan, two-layer) + - Fix orphan backend append to preserve trailing whitespace via readUntrimmed() + - Add `SquadStateContext` interface and `resolveSquadState()` factory in resolution module + - Add `StateBackendStorageAdapter` — bridges StateBackend as a StorageProvider so SDK modules that accept `storage: StorageProvider` work with git-notes and orphan backends + - Add `storage` field to `SquadStateContext` — local uses FSStorageProvider directly, orphan/two-layer use the adapter + - Export `StateBackendStorageAdapter` from SDK public API + - Wire `resolveSquadState()` into CLI entry so the state backend is resolved once at startup + - Pass pre-resolved `stateContext` through to watch config to avoid redundant resolution + - Add `notes-protocol.md` template — agent contract for git-notes state (namespaces, JSON schema, fetch/push, conflict handling) + - Add `scripts/notes/fetch.ps1` template — fetch notes + one-time refspec setup + merge after conflict + - Add `scripts/notes/write-note.ps1` template — agent helper for writing notes with JSON validation and push retry + - Update state-backends docs with "Using with Copilot CLI Sessions" section (copilot-instructions snippet, promotion flow, template index) + - This is the SDK foundation for making state backends squad-wide (Phase 1) + +- bbcbf7b: feat(sdk): Add Microsoft Teams communication adapter + + BREAKING: `createCommunicationAdapter` is now async (returns `Promise`). + Callers must await the result. + + New Teams adapter for bidirectional chat via Microsoft Graph API. + Supports browser auth (PKCE), device code flow, token caching, + 1:1 chat and channel messaging. + +- e11b5d3: feat: add tiered-memory skill for hot/cold/wiki agent context management +- e0898ad: fix(sdk): wire `squad_route` tool handler to actually create target sessions + + The `squad_route` tool is documented in `packages/squad-sdk/README.md`, + `docs/src/content/docs/reference/sdk.md`, + `docs/src/content/docs/reference/api-reference.md`, and the + `build-autonomous-agent` guide as routing tasks and creating new sessions + for the target agent. The previous implementation returned + `resultType: 'success'` with the hard-coded text "Session creation will be + implemented when session lifecycle is in place" without ever spawning a + session. SDK embedders following the documented usage + (`toolRegistry.getTool('squad_route').handler({ ... })`) received a + confident "Task routed to X" success payload while no agent ever started — + a silent no-op masquerading as success. + + This change: + + - Adds an optional 5th positional `fanOutDepsGetter` constructor parameter + to `ToolRegistry`. Existing 4-arg constructions are unaffected. + - When `fanOutDepsGetter` returns dependencies, `squad_route` calls + `spawnParallel` with a single config (charter compile → model resolve → + `createSession` → initial message), matching the SDK `Coordinator` + fan-out path. + - When `fanOutDepsGetter` is absent or returns `undefined`, the handler + returns `resultType: 'failure'` with `error: 'fan-out-deps-unavailable'` + and remediation guidance, replacing the previous false-success. + - Normalizes `targetAgent` to lowercase (matching charter-loading convention). + - Distinguishes roster "not found" errors from infrastructure I/O failures. + - Updates `docs/src/content/docs/guide/build-autonomous-agent.md` with a + note about the `fanOutDepsGetter` requirement and `fan-out-deps-unavailable` + failure mode. + + Behavior change for embedders that relied on the stub's unconditional + success: those calls now return an honest failure. Remediation is to + either (a) construct `ToolRegistry` with a `fanOutDepsGetter`, or + (b) intercept `squad_route` via `SquadSessionHooks.onPreToolUse`. + + Related: #1029 (named-agent delegation answering inline) — different code + path (Copilot CLI `task` tool / coordinator prompt), not closed by this PR, + but shares the same root-cause family of silent-no-op delegation primitives. + +### Patch Changes + +- 36eed05: Fix hardcoded "Brady" in template files — LLMs now use actual git username instead of example name (closes #977) +- 8c33f9f: fix: bump CLI version to 0.9.7-preview; align E2E skill and policy gate with CONTRIBUTING.md + + The insider publish workflow stamped `@bradygaster/squad-cli` at `0.9.6-build.4`, + which violates the prerelease version policy gate. Per CONTRIBUTING.md, the correct + local dev version is `{next-version}-preview`. + + - `packages/squad-cli/package.json`: `0.9.6-build.4` → `0.9.7-preview` + - All 4 copies of `e2e-template-testing/SKILL.md` (root `templates/`, + `packages/squad-sdk/templates/`, `packages/squad-cli/templates/`, + `.squad-templates/`): + - **Build commands** aligned with CONTRIBUTING.md (lines 253–256): use workspace + flags `npm run build -w packages/squad-sdk && npm run build -w packages/squad-cli` + and `npm link -w packages/squad-cli` instead of shell `cd` + bare `npm run build` + - **Version verify text** updated to version-agnostic `x.y.z-preview` placeholder + with an explicit note that the `-preview` suffix is required, linking to + CONTRIBUTING.md for the full local dev setup + - `.github/workflows/squad-ci.yml` — Prerelease Version Guard: relaxed regex from + `/-/` (any hyphen) to `/-/ && not /^\d+\.\d+\.\d+-preview$/` so the CONTRIBUTING.md- + sanctioned `-preview` suffix is allowed while all other prerelease tags (e.g. + `-build.4`, `-alpha`, `-beta`) are still blocked + +- 490adf3: fix: context overflow sentinel and coordinator size reduction (retroactive for #1035) + + `squad.agent.md` was ~95.8KB and could be silently dropped from context in long sessions, degrading the coordinator to vanilla Copilot with no safety rails. + + Changes shipped in PR #1035 (merged without changeset): + + - **Canary sentinel** — `SQUAD_COORDINATOR_CANARY_a8f3` token appended to `squad.agent.md`; `copilot-instructions.md` checks for it and warns if the coordinator was dropped from context + - **Coordinator slimming** — `squad.agent.md` reduced ~42% (95.8KB → ~55KB) by extracting to on-demand reference files: `spawn-reference.md`, `after-agent-reference.md`, `model-selection-reference.md`, `ralph-reference.md`, `worktree-reference.md`, `client-compatibility-reference.md` + - **Scribe charter extraction** — Scribe's inline section moved from `squad.agent.md` to a standalone `scribe-charter.md` + - **E2E skill overhaul** — Fast-fail rules, PII protection, anti-skip enforcement, live progress tracking comment (updated per step), duration tracking, Windows encoding fix, `--allow-all-tools` documentation, progressive verdicting, agent run time budget + - **Build fix** — CLI dep changed from `@bradygaster/squad-sdk: >=0.9.0` to `>=0.9.0-0` so npm workspace resolution uses the local prerelease package instead of a stale published version + + All 4 template locations synced: `.squad-templates/`, `templates/`, `packages/squad-cli/templates/`, `packages/squad-sdk/templates/`. + + Closes #1017 + +- e5f4ca5: Fix coordinator and Scribe templates so spawned agents receive and write the resolved current datetime instead of placeholder text. +- 42c9dd3: Fix 5 bugs: dotted repo names, icon spacing, board owner, charter passing, missing playbooks +- 70a3781: Fix permission handler to use `approve-once` instead of deprecated `approved` kind, aligning with Copilot CLI v1.0.54+ permission contract +- d8c1382: Sync squad.agent.md roster when agents added to team.md +- 27f07cf: Warn when squad.agent.md template is missing during upgrade or init instead of silently skipping file creation. Adds `warnings` field to `InitResult` for structured error reporting. +- 09cd6c1: Fix state-backend and upgrade regressions (#1163, #1185, #1190, #1191, #1194) + + **Bug A (P0) — Permission contract mismatch** (#1191) + The Copilot SDK changed the valid permission result `kind` from `"approved"` to + `"approve-once"`. Squad was still returning `{ kind: 'approved' }`, causing all + agent sessions to fail permission checks immediately. Fixed in: + + - `cli/shell/index.ts` — `approveAllPermissions` handler now returns `{ kind: 'approve-once' }` + - `adapter/types.ts` — `SquadPermissionRequestResult.kind` union includes `'approve-once'` + - `adapter/client.ts` — error hint updated to reference the correct `kind` value + + **Bug B (P1) — Hard-throw in `resolveStateBackend()` when explicit backend fails** (#1185, #1190) + When a backend configured in `config.json` failed to initialize (e.g., no git repo + available), Squad threw a fatal error and refused to start. Now always warns and + falls back to `local` so operators can fix config without losing work. + + **Bug C (P1) — Silent git-notes→two-layer migration** (#1163) + `normalizeBackendType()` silently mapped `'git-notes'` to `'two-layer'` with no + user notification. Now emits a `console.warn()` directing users to update their + `config.json`. + + **Bug F (P3) — Windows `toRelative()` drive-letter case mismatch** + `StateBackendStorageAdapter.toRelative()` used a simple string prefix comparison + after normalizing separators. On Windows, `C:\` vs `c:\` drive-letter case + differences caused the prefix check to fail, returning full absolute paths as + git-notes keys (corruption). Now uses `path.resolve()` and case-insensitive + comparison on `process.platform === 'win32'`. + + **Issue #1194 — Externalized state paths not followed by runtime commands** + Adds `effectiveSquadDir()` and `resolveStateDir()` helpers that follow the + `stateLocation: 'external'` marker in `.squad/config.json`. Updates `loop`, + `watch`, `plugin`, `doctor` commands and `shell` (lifecycle, coordinator, index) + to use the effective state dir for reading `team.md`, `routing.md`, `agents/`, + `plugins/`, and other state files. + +- 2129ad7: Fix triage label slug derivation: use `slugify()` instead of `toLowerCase()` so multi-word agent names produce valid GitHub labels (e.g. "Steve Rogers" → `squad:steve-rogers` instead of `squad:steve rogers`). + + Pre-create all `squad:{member}` labels at watch startup via `ensureTag()` so `gh issue edit --add-label` never fails on missing labels. + +- a299b3c: fix: use TEMPLATE_MANIFEST to drive skill installation instead of wholesale directory copy + + Both sdkInitSquad() and syncAllSkills() previously copied the entire templates/skills/ + directory, ignoring the curated 8-skill subset declared in TEMPLATE_MANIFEST. + This meant all 37+ template skills shipped on every init/upgrade, and + overwriteOnUpgrade was never consulted. + + Now both code paths iterate TEMPLATE_MANIFEST entries: + + - init (SDK): only the 8 manifest skills are copied on first init + - upgrade (CLI): syncAllSkills() reads manifest entries, respects overwriteOnUpgrade + + Fixes #833 + +- 29cedd0: perf(agents): parallelize charter discovery with concurrency limit to reduce multi-agent load time +- 10f5036: perf(resolution): memoize squad-dir lookups; deduplicate squads.json reads to reduce filesystem I/O on repeated resolution calls +- 892bd4f: perf(scheduler): convert sequential async execution to concurrent with bounded concurrency to improve multi-agent dispatch throughput +- 3bd1843: feat: add declarative plugin behavior context proof + + Adds static plugin metadata, lifecycle state, runtime context injection, + declarative provider contracts, and behavior simulations for Graphify, + MemPalace, and Index Server plugin samples. Enabled plugins can now contribute + installed static guidance and typed memory/knowledge provider summaries to + spawned-agent prompts while preserving the no-execution security boundary. + +- aa91ba4: Add retro enforcement skill with Test-RetroOverdue and ceremonies template update. + + - New skill: retro-enforcement - coordinator integration pattern for automated retro cadence enforcement + - Action items tracked as GitHub Issues (not markdown checklists) + - Production data: 0% to 100% completion rate after switching formats + - Test-RetroOverdue PowerShell function detects overdue retros and blocks work queue + - Ceremonies template updated with enforcement-aware retrospective definition + +- 8456549: Add SDK feature parity batch 2 — 64 tests covering manual ceremonies (#27), ceremony cooldown (#28), human team members (#36), constraint budget enforcement (#49 — rate limiter, file-write guards, shell restrictions, PII scrubbing), multi-agent artifact coordination (#50), and builder validation edge cases. +- 4f2de95: test: SDK feature parity batch 3 — 46 tests for #31, #47, #45, #46 + + Adds 46 automated tests covering 4 SDK features from the #341 parity matrix: + + - RalphMonitor idle-watch mode (#31): construction, event handling, stale session detection + - Platform detection (#47): GitHub/Azure DevOps URL parsing, detectPlatformFromUrl + - Reviewer lockout (#45): rejection protocol, per-artifact scope, persistence + - Deadlock handling (#46): all-agents-locked detection, clearLockout escalation, recovery + +- eb17e15: Fix squad-commands skill routing and configuration for Copilot integration + + - **templates.ts**: Correct destination path for squad-commands SKILL.md from `skills/squad-commands/SKILL.md` to `../.copilot/skills/squad-commands/SKILL.md` to match other built-in skills + - **init.ts**: Add `'squad-commands'` to MANIFEST_SKILL_NAMES array to include the skill in project initialization + - **squad-commands SKILL.md**: Convert triggers from YAML list to inline array format and remove generic triggers ("help", "how do I") that conflict with other skills; retain: "squad commands", "what can squad do", "show me squad options", "slash commands" + - **Template sync**: Regenerate all mirrors via sync-templates.mjs to propagate routing updates to .copilot and .squad templates + +- a3419b5: Bump `@github/copilot-sdk` from `^0.1.32` to `^0.3.0` to fix ESM module resolution error (ERR_MODULE_NOT_FOUND for vscode-jsonrpc/node). Add explicit GitHub repo config support in `.squad/config.json` (`{ "github": { "owner": "...", "repo": "..." } }`) so platform adapter prefers user-specified repo over auto-detection from origin remote. (closes #1062, closes #905) +- 14917c5: State backend hardening: retry with exponential backoff for transient git errors, circuit-breaker to prevent cascading failures, read-only startup verification, and observable error surfacing replacing silent swallowing. +- 84872b1: Harden runtime state tools so write, append, and delete only mutate approved Squad runtime state paths, and refresh prompt templates to require state-tool persistence and literal datetime propagation. +- a543f93: Fix Windows Azure CLI execution and ADO state mapping in squad watch diff --git a/packages/squad-sdk/package.json b/packages/squad-sdk/package.json index b6970f041..1dc9b7666 100644 --- a/packages/squad-sdk/package.json +++ b/packages/squad-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@bradygaster/squad-sdk", - "version": "0.9.6-preview.13", + "version": "0.10.0", "description": "Squad SDK — Programmable multi-agent runtime for GitHub Copilot", "type": "module", "main": "./dist/index.js", diff --git a/packages/squad-sdk/templates/skills/fact-checking/SKILL.md b/packages/squad-sdk/templates/skills/fact-checking/SKILL.md new file mode 100644 index 000000000..f7f7873e5 --- /dev/null +++ b/packages/squad-sdk/templates/skills/fact-checking/SKILL.md @@ -0,0 +1,61 @@ +--- +name: fact-checking +description: Review and validate claims using counter-hypothesis testing. Use when verifying technical content, checking references, validating API endpoints, or performing quality assurance on deliverables. +license: MIT +compatibility: Requires access to external references and APIs +metadata: + author: squad + version: "1.0.0" + domain: quality, verification + confidence: low + last_validated: "2026-03-01" +--- + +# Skill: Fact Checking + +## Context +Codifies the challenger agent review output format and methodology so any agent performing fact-checking or review produces consistent, structured output. + +## Pattern + +### Review Methodology + +For every claim or deliverable under review: +1. Ask: "What evidence supports this? What would disprove it?" +2. Generate counter-hypotheses and test them against available data +3. Verify URLs, package names, API endpoints, and external references actually exist +4. Flag confidence levels: ✅ Verified, ⚠️ Unverified, ❌ Contradicted + +### Review Output Format + +When reviewing another agent's work, use this template: + +``` +### Fact Check — {deliverable name} +**Claims verified:** {count} +**Issues found:** {count} + +| # | Claim | Status | Evidence/Notes | +|---|-------|--------|---------------| +| 1 | {claim} | ✅/⚠️/❌ | {supporting or contradicting evidence} | + +**Counter-hypotheses tested:** +- {alternative explanation + result} + +**Verdict:** {PASS / PASS WITH NOTES / NEEDS REVISION} +``` + +### Confidence Levels + +- ✅ **Verified** — evidence confirms the claim +- ⚠️ **Unverified** — cannot confirm or deny; suggest verification method +- ❌ **Contradicted** — evidence disproves the claim + +### Ceremony Integration + +Auto-trigger this skill before any architecture decision, or when an agent claim contains superlatives or percentage thresholds (e.g., "saves 75%", "always", "never"). The coordinator spawns the challenger agent with: + +``` +Challenger — fact-check {agent}'s claim: "{claim}" +Cite evidence for every verdict. Max 3 investigation cycles. +``` \ No newline at end of file diff --git a/packages/squad-sdk/templates/workflow-wiring-appendix-a-code-reviewer.md b/packages/squad-sdk/templates/workflow-wiring-appendix-a-code-reviewer.md new file mode 100644 index 000000000..c447f7f9c --- /dev/null +++ b/packages/squad-sdk/templates/workflow-wiring-appendix-a-code-reviewer.md @@ -0,0 +1,131 @@ +# Appendix A: Wiring a Code Reviewer — Complete Walkthrough + +> End-to-end example of adding a code reviewer to your squad and wiring their gate so it actually gets enforced. This walkthrough addresses a common failure: a reviewer is on the roster but never reviews a single PR because the gate wasn't wired. + +## The Problem This Solves + +Adding a reviewer to `team.md` gives them an identity. It does NOT: +- Tell the coordinator to route PRs to them +- Prevent PRs from being merged without their approval +- Prevent issues from being closed before review happens + +**What goes wrong without enforcement:** A reviewer can be on the roster as "Reviewer" from day one. Their charter says they review PRs. The routing table says "PR code review → {ReviewerName}." But PRs get merged and issues get closed without them ever being spawned. Why? + +Because the routing table says WHO handles what — it's for incoming requests ("review PR #42"). It does NOT say "after every agent completes work, route their output to {ReviewerName}." The coordinator routes work TO agents, but nothing tells it to route COMPLETED work to a reviewer. The "After Agent Work" flow in `squad.agent.md` says: collect results → present → spawn Scribe. No review step. + +**The fix has three layers:** + +| Layer | What it does | Where it lives | +|-------|-------------|----------------| +| Identity | Reviewer exists and knows how to review | `team.md` roster + `charter.md` | +| Routing | User can explicitly request "review this" | `routing.md` routing table | +| **Enforcement** | Coordinator MUST route every PR to reviewer before merge | `routing.md` Rules section + `issue-lifecycle.md` post-work steps | + +Most squads get layers 1 and 2 right. Layer 3 — enforcement — is what's usually missing. + +## Step-by-Step Walkthrough + +### Step 1: Create the reviewer's identity + +Create `.squad/agents/{name}/charter.md`: + +```markdown +# {Name} — Code Reviewer + +## Identity +- **Name:** {Name} +- **Role:** Code Reviewer +- **Expertise:** Code quality, correctness, test coverage, security, patterns +- **Style:** Thorough, fair, specific. Provides actionable feedback. + +## What I Own +- Reviewing PRs for code quality, correctness, and test coverage +- Identifying bugs, security issues, and design problems +- Providing specific, actionable feedback (not vague suggestions) + +## How I Review +1. Read the PR diff completely +2. Check: does it do what the issue asked for? +3. Check: are there tests? Do they cover the important cases? +4. Check: are there bugs, edge cases, or security issues? +5. Check: does it follow project patterns and conventions? +6. Verdict: APPROVE or REJECT with specific feedback + +## Boundaries +**I handle:** Code review, PR review, quality gates +**I don't handle:** Implementation, design, research, documentation + +## On REJECT +I provide specific feedback: what's wrong, why, and what to do instead. +The original author fixes their work. I re-review after fixes. +``` + +Create `.squad/agents/{name}/history.md` seeded with project context. + +### Step 2: Add to team.md roster + +```markdown +| 👑 {Name} | Code Reviewer | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing table entry + +In `routing.md` → routing table: + +```markdown +| PR code review | 👑 {Name} | — | "Review PR #42", code quality, finding reports | +``` + +**⚠️ This is necessary but NOT sufficient.** This only handles explicit review requests. It does NOT enforce automatic review of every PR. + +### Step 4: Add enforcement rule (THIS IS THE CRITICAL STEP) + +In `routing.md` → `## Rules` section, add a numbered rule: + +```markdown +N. **{Name} PR Gate** — every PR created by any agent MUST be reviewed by {Name} + before merge. The coordinator spawns {Name} (sync) with the PR diff after + the author pushes and creates the PR. On REJECT, the original author addresses + feedback. On APPROVE, the coordinator merges via `gh pr merge`. No PR merges + without {Name}'s approval. +``` + +**Why this works when the routing table alone didn't:** The routing table is for matching incoming work to agents. Rules are behavioral constraints the coordinator must follow AFTER work completes. The rule says "after a PR exists, you MUST do X before proceeding." The routing table says "if someone asks for a review, route to X." + +### Step 5: Wire into issue-lifecycle.md + +In `.squad/templates/issue-lifecycle.md`, the "Coordinator Post-Work Steps" section should reference your reviewer by name: + +```markdown +4. **Route to reviewer.** Spawn {Name} (sync) with the PR diff for code review. +``` + +This is the operational detail — the step-by-step instructions the coordinator follows after an agent completes issue work. The routing rule (Step 4) is the mandate; the lifecycle template is the procedure. + +### Step 6: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 7: Verify + +Ask yourself these questions: + +- [ ] If a clean session coordinator reads `routing.md` Rules, will it know to route PRs to this reviewer? → Check rule N exists. +- [ ] If an agent completes work and pushes a PR, does the coordinator's post-work flow include a review step? → Check `issue-lifecycle.md` step 4. +- [ ] Can the coordinator merge a PR without the reviewer's approval? → The rule should say "No PR merges without {Name}'s approval." +- [ ] Can the coordinator close an issue without a merged PR? → Check the issue closure rule exists. + +If any answer is wrong, you have a gap. + +## What Each File Controls (Summary) + +| File | What it contributes to the reviewer gate | +|------|----------------------------------------| +| `charter.md` | WHO the reviewer is and HOW they review | +| `team.md` | That the reviewer EXISTS on the team | +| `routing.md` routing table | That explicit review requests go to this reviewer | +| `routing.md` Rules section | That the coordinator MUST route EVERY PR to this reviewer (enforcement) | +| `issue-lifecycle.md` | The step-by-step procedure for the post-work review flow | +| `casting/registry.json` | Persistent name tracking | + +**Remove any one of these and the gate has a hole.** The most commonly missed piece is the Rules section entry (Step 4). diff --git a/packages/squad-sdk/templates/workflow-wiring-appendix-b-documenter.md b/packages/squad-sdk/templates/workflow-wiring-appendix-b-documenter.md new file mode 100644 index 000000000..fb8cd26aa --- /dev/null +++ b/packages/squad-sdk/templates/workflow-wiring-appendix-b-documenter.md @@ -0,0 +1,140 @@ +# Appendix B: Wiring a Documenter/Librarian — Complete Walkthrough + +> End-to-end example of adding a documenter role that ensures significant changes are documented. This is a FOLLOW-UP TRIGGER pattern — not a gate (which blocks), but an automatic downstream task that fires after work completes. + +## The Problem This Solves + +Your project has agents building features, fixing bugs, and writing tools. But nobody documents what was built, how to use it, or what changed. Documentation happens only when someone explicitly asks — and by then, the context is lost. + +A documenter/librarian role solves this by automatically evaluating whether completed work needs documentation and producing it if so. + +## Gate vs Follow-Up Trigger + +| Pattern | Blocks work? | When it runs | Example | +|---------|-------------|-------------|---------| +| **Gate** (Appendix A) | Yes — work cannot proceed without approval | Before merge | Code reviewer must approve PR | +| **Follow-up trigger** | No — work proceeds, documentation happens in parallel | After merge | Documenter evaluates if docs are needed | + +A documenter is typically a follow-up trigger, not a gate. You don't want documentation review to block a hotfix from merging. But you DO want documentation to happen automatically after significant changes. + +## Step-by-Step Walkthrough + +### Step 1: Create the documenter's identity + +Create `.squad/agents/{name}/charter.md`: + +```markdown +# {Name} — Documenter + +## Identity +- **Name:** {Name} +- **Role:** Documenter / Librarian +- **Expertise:** Documentation, guides, READMEs, changelogs, knowledge management +- **Style:** Clear, thorough, user-focused. Makes complex things understandable. + +## What I Own +- Evaluating whether completed work needs documentation +- Writing/updating READMEs, guides, and runbooks +- Maintaining a docs index so nothing gets lost +- Summarizing design decisions and architectural changes + +## How I Work +1. Read the PR diff or agent output +2. Assess: does this change user-facing behavior? Add a new feature? Change configuration? +3. If yes: write or update the relevant documentation +4. If no: report "no docs needed" with brief justification + +## Boundaries +**I handle:** Documentation, guides, READMEs, summaries, knowledge management +**I don't handle:** Code implementation, code review, research, operations +``` + +Create `.squad/agents/{name}/history.md` seeded with project context. + +### Step 2: Add to team.md roster + +```markdown +| 📝 {Name} | Documenter | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing table entry + +In `routing.md` → routing table: + +```markdown +| Documentation, reports, summaries | 📝 {Name} | `docs/` | "Write docs for X", "Summarize this", guides, READMEs | +``` + +### Step 4: Add follow-up trigger rule + +In `routing.md` → `## Rules` section, add a numbered rule: + +```markdown +N. **Documentation follow-up** — after any PR is merged that adds or modifies + user-facing features, scripts, tools, or configuration, the coordinator + spawns {Name} (background) to evaluate whether documentation is needed. + {Name} reads the merged PR diff and either writes/updates docs or reports + "no docs needed." This is a follow-up, not a gate — it does not block + the merge. +``` + +**Why a rule and not a ceremony:** Ceremonies are structured multi-participant meetings. This is a single-agent follow-up task. A routing rule is simpler and more appropriate. + +**Why background, not sync:** Documentation doesn't block other work. The documenter runs in parallel with whatever comes next. + +### Step 5: Wire into the coordinator's post-merge flow + +This is the trickiest part. The coordinator's After Agent Work flow doesn't currently have a "post-merge" hook. You wire this through the issue-lifecycle template. + +In `.squad/templates/issue-lifecycle.md`, after the merge step, add: + +```markdown +8. **Documentation follow-up.** After merge, check routing.md Rules for + documentation follow-up rule. If present, spawn the documenter (background) + with the merged PR diff to evaluate whether docs are needed. +``` + +Alternatively, you can wire this as an `after` ceremony in `ceremonies.md`: + +```yaml +- name: "Documentation Check" + when: "after" + condition: "PR merged that adds features, scripts, tools, or config changes" + facilitator: "{DocumenterName}" + participants: ["{DocumenterName}"] + output: "Docs written/updated, or 'no docs needed' with justification" +``` + +### Step 6: Worktree for doc changes + +If the documenter produces files, they need a worktree — docs are files too. The coordinator should: +1. Create a worktree for the doc update (e.g., `squad/{issue}-docs`) +2. The documenter commits and pushes +3. A PR is created for the docs +4. The docs PR goes through the normal review flow (including the code reviewer if you have one) + +This means doc changes also get reviewed. The documenter is not exempt from the review gate. + +### Step 7: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 8: Verify + +- [ ] After a feature PR merges, does the coordinator spawn the documenter? → Check the routing rule exists. +- [ ] Does the documenter get a worktree for their work? → Check the worktree rule covers docs. +- [ ] Do doc changes go through the review gate? → They should — docs are files, files need PRs, PRs need review. +- [ ] Is the follow-up non-blocking? → The documenter should be background, not sync. + +## What Each File Controls (Summary) + +| File | What it contributes | +|------|-------------------| +| `charter.md` | WHO the documenter is and HOW they evaluate | +| `team.md` | That the documenter EXISTS | +| `routing.md` routing table | That explicit doc requests go to this member | +| `routing.md` Rules section | That the coordinator MUST spawn docs evaluation after merges (enforcement) | +| `issue-lifecycle.md` or `ceremonies.md` | The procedural hook: when exactly the follow-up fires | +| `casting/registry.json` | Persistent name tracking | + +**The most commonly missed piece:** The Rules section entry (Step 4). Without it, the documenter only runs when someone explicitly says "write docs for X." The whole point is that it runs automatically. diff --git a/packages/squad-sdk/templates/workflow-wiring-guide.md b/packages/squad-sdk/templates/workflow-wiring-guide.md new file mode 100644 index 000000000..853a13d0a --- /dev/null +++ b/packages/squad-sdk/templates/workflow-wiring-guide.md @@ -0,0 +1,276 @@ +# Squad Workflow Wiring Guide + +> How to wire up new team members, reviewer gates, and custom workflows so they actually get enforced by the coordinator — even in a clean session with no prior memory. + +## Why This Guide Exists + +The Squad framework (`squad.agent.md`) provides generic orchestration primitives. **It does not prescribe a specific workflow.** Your project's workflow — whether that's "all code goes through PRs and reviews" or "just commit to main" — must be wired into project-level configuration files. + +If a workflow rule exists only in someone's memory, in a chat transcript, or in `decisions.md` but NOT in a configuration file the coordinator reads at decision time — **it will not be followed in a clean session.** + +### Why Existing Patterns Aren't Enough + +The Squad framework already has concepts for routing tables, reviewer roles, and ceremonies. But having these concepts does NOT mean they work automatically: + +- **Adding a reviewer to the roster ≠ enforcing reviews.** A reviewer can be on the roster with "Reviewer" as their role and never review a single PR — because no RULE in `routing.md` tells the coordinator to route PRs to them. The roster says WHO exists. Rules say WHAT they enforce. + +- **Capturing a decision ≠ enforcing it.** `decisions.md` may contain "every change must go through a PR" and "only {ReviewerName} closes PRs." These can get buried in a large file that the coordinator reads for context but doesn't treat as enforcement rules. A decision is a historical record. A routing rule is an enforceable constraint. + +- **Describing a lifecycle ≠ wiring it.** `squad.agent.md` describes issue→branch→PR→review→merge. But if the After Agent Work section (the flow the coordinator actually follows after every agent completes) has no push/PR/review step, the lifecycle is described conceptually but never connected to the coordinator's actual decision flow. + +**The pattern that works:** A numbered rule in `routing.md` → Rules section. The coordinator reads this section, treats each rule as a constraint, and follows them. If your workflow isn't a numbered rule, it's a suggestion. + +--- + +## Configuration Surface Area + +The coordinator reads these files to decide how to behave. If your workflow isn't encoded in one of these, it doesn't exist. + +| File | What It Controls | Read When | +|------|-----------------|-----------| +| `routing.md` | WHO handles what, behavioral RULES, reviewer GATES | Every session start, before every routing decision | +| `ceremonies.md` | Auto-triggered ceremonies (before/after work batches) | Before spawning work batches, after completion | +| `templates/issue-lifecycle.md` | Git workflow: push, PR, review, merge, issue closure | When spawning agents for issue-linked work | +| Agent `charter.md` | Per-agent identity, boundaries, behavior | Inlined into every spawn prompt | +| `team.md` | Roster, member capabilities | Session start | +| `decisions.md` | Captured decisions and directives | Read by agents at spawn time | + +### How They Interact + +``` +User request arrives + → Coordinator reads routing.md (WHO handles this?) + → Coordinator checks ceremonies.md (any auto-triggered "before" ceremony?) + → Coordinator reads agent charter.md (inline into spawn prompt) + → If issue-linked: coordinator reads issue-lifecycle.md (add ISSUE CONTEXT to spawn prompt) + → Agent works + → Coordinator follows After Agent Work flow + → Coordinator checks ceremonies.md (any auto-triggered "after" ceremony?) + → Coordinator checks routing.md Rules section (any post-work rules to enforce?) +``` + +**The critical insight:** `routing.md` Rules section and `ceremonies.md` are the two enforcement mechanisms. If a rule isn't in one of these, the coordinator has no way to know about it. + +--- + +## How to Wire Up a New Team Member + +### Step 1: Create the member (files) + +``` +.squad/agents/{name}/ + charter.md ← Identity, role, boundaries, what they own + history.md ← Seeded with project context from team.md +``` + +### Step 2: Add to roster (`team.md`) + +Add a row to the `## Members` table: +``` +| {emoji} {Name} | {Role} | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing entry (`routing.md`) + +Add a row to the routing table: +``` +| {Work Type} | {emoji} {Name} | {Output Location} | {Examples} | +``` + +### Step 4: Add issue routing (if applicable) + +Add to the Issue Routing table in `routing.md`: +``` +| squad:{name} | {Description of work} | {emoji} {Name} | +``` + +### Step 5: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 6: Wire any gates (if this member is a reviewer/gate) + +**This is the step most people miss.** If the new member should review or gate other members' work, you need to wire enforcement. See "How to Wire Up a Reviewer Gate" below. + +--- + +## How to Wire Up a Reviewer Gate + +A reviewer gate means: "Agent X must review Agent Y's output before it proceeds." The framework supports this but does NOT automatically enforce it. You must wire it. + +### Option A: Routing Rule (recommended for simple gates) + +Add to `routing.md` → `## Rules` section: + +```markdown +N. **{GateName} Gate** — Every {output type} from {Author} MUST be reviewed by {ReviewerName} before {next step}. The coordinator routes {Author}'s output to {ReviewerName} (sync spawn), collects the verdict, and only proceeds if approved. On rejection, {Author} revises based on {ReviewerName}'s feedback. +``` + +**Example — reviewer for all PRs:** +```markdown +9. **{ReviewerName} PR Gate** — Every PR created by any agent MUST be reviewed by {ReviewerName} before merge. The coordinator spawns {ReviewerName} (sync) with the PR diff, collects APPROVE/REJECT verdict. On rejection, the original author addresses feedback. +``` + +**Example — design review gate:** +```markdown +10. **{DesignReviewer} Design Gate** — Every design doc produced by the architect MUST be reviewed by {DesignReviewer} before implementation begins. {DesignReviewer} always rejects the first draft on concept/approach. Implementation is BLOCKED until {DesignReviewer} approves. +``` + +**Why this works:** The coordinator reads the Rules section before and after every work batch. Rules are behavioral constraints the coordinator must follow. + +### Option B: Ceremony (recommended for multi-participant gates) + +Add to `ceremonies.md` using the Markdown table format the file uses: + +```markdown +## Design Review + +| Field | Value | +|-------|-------| +| **Trigger** | auto | +| **When** | before | +| **Condition** | task involves implementing a design doc | +| **Facilitator** | {DesignReviewer} | +| **Participants** | Architect, {DesignReviewer} | +| **Time budget** | focused | +| **Enabled** | ✅ yes | + +**Agenda:** +1. Read the design doc +2. Challenge the premise and approach +3. Demand alternatives and evidence +4. Verdict: APPROVE or REJECT +``` + +**Why this works:** The coordinator checks ceremonies.md for `before` ceremonies whose condition matches the current task. If matched, the ceremony runs before work begins. + +### Option A vs Option B + +| Use Case | Use Routing Rule | Use Ceremony | +|----------|-----------------|--------------| +| Simple 1-on-1 review (reviewer → author) | ✅ | Overkill | +| Multi-participant alignment (3+ agents) | Too simple | ✅ | +| Needs structured facilitation | No | ✅ | +| Must run automatically before specific work | Either works | ✅ | +| One-line behavioral constraint | ✅ | Overkill | + +--- + +## How to Wire Up an Issue Lifecycle (Git Workflow) + +This is where you define what happens after an agent completes work on a GitHub issue. The framework references `.squad/templates/issue-lifecycle.md` but does NOT create it — you must create it yourself. + +> **⚠️ This file is required if your project uses GitHub Issues Mode.** Without it, the coordinator has no post-work steps for push/PR/review and will treat agent commit as "done." + +See `.squad/templates/issue-lifecycle.md` for the full template if your project already has one. If not, create it following the pattern below. + +### Step 1: Create `templates/issue-lifecycle.md` + +Create `.squad/templates/issue-lifecycle.md` with your project's git workflow. At minimum it should include: + +- An ISSUE CONTEXT block template (for spawn prompts) +- Coordinator post-work steps (verify push → verify PR → route to reviewer → merge on approval) +- Issue closure rules (PR merge auto-close vs manual close) +- Worktree requirements (if applicable) + +### Step 2: Add enforcement rules to `routing.md` + +Add numbered rules to the `## Rules` section that reference the lifecycle: + +```markdown +N. **Issue lifecycle enforcement** — all issue-linked work follows the lifecycle + in `.squad/templates/issue-lifecycle.md`. The coordinator adds the ISSUE CONTEXT + block to spawn prompts and follows the post-work steps (verify push → verify PR + → route to reviewer → merge on approval). Read `issue-lifecycle.md` before + spawning any agent for issue work. + +N+1. **{ReviewerName} PR Gate** — every PR created by any agent MUST be reviewed + by {ReviewerName} before merge. The coordinator spawns {ReviewerName} (sync) + with the PR diff. On REJECT, the original author addresses feedback. On APPROVE, + the coordinator merges. No PR merges without {ReviewerName}'s approval. + +N+2. **Issue closure restriction** — issues that produced files (code, docs, scripts, + designs, tests) close ONLY via PR merge auto-close ("Closes #N" in PR body). + Never use `gh issue close` for file-producing work. Exception: tracking/strategic + issues and superseded issues may be closed with a comment. + +N+3. **Worktree for all file-producing work** — every task that creates or modifies + files (including documentation) requires a worktree. Exceptions: read-only queries, + Scribe (.squad/ state), pure analysis producing no files. +``` + +### Step 3: Verify your wiring + +After creating both files, run the verification checklist (below) to confirm a clean session coordinator would follow the lifecycle. + +--- + +## How to Wire Up a Custom Workflow Step + +If you need something that isn't a reviewer gate or issue lifecycle — for example, "always run tests before pushing" or "docs must be reviewed by the author before merge" — here's where to put it: + +### If it's a behavioral rule the coordinator should always follow: +→ Add to `routing.md` → `## Rules` section + +### If it should trigger automatically before/after specific work: +→ Add to `ceremonies.md` as a `before` or `after` ceremony + +### If it's something agents should do as part of their work: +→ Add to the agent's `charter.md` under a new section + +### If it's something that applies only to issue-linked work: +→ Add to `templates/issue-lifecycle.md` + +### If it's a team-wide constraint that should be visible to all agents: +→ Capture as a decision in `decisions.md` (via directive or decision inbox) + +--- + +## Verification Checklist + +After wiring any new member, gate, or workflow, verify: + +- [ ] **Clean session test:** Start a new session (no memory). Give a task. Does the coordinator follow the new rule? +- [ ] **File completeness:** Is the rule/gate/workflow encoded in a file the coordinator reads? (routing.md, ceremonies.md, issue-lifecycle.md, charter.md) +- [ ] **No verbal-only rules:** Is there anything the coordinator should do that's only in chat history or your memory? If yes, it will be lost on session restart. +- [ ] **Gate enforcement:** If you added a reviewer gate, does the routing.md Rules section or ceremonies.md explicitly say the coordinator must route to the reviewer? "Having a reviewer on the roster" is not the same as "enforcing that they review." +- [ ] **Issue lifecycle:** If your project uses PRs, does `templates/issue-lifecycle.md` exist? Does routing.md reference it? + +--- + +## Common Mistakes + +1. **Adding a reviewer to the roster but not wiring a gate.** Having a reviewer on the team doesn't mean they review anything. You must add a rule in routing.md that says "route PRs to {ReviewerName}." + +2. **Closing issues via `gh issue close` instead of PR merge.** If your project uses PRs, issue closure should happen via "Closes #N" in the PR body. Wire this in issue-lifecycle.md. + +3. **Writing docs/scripts directly on main.** If your project requires branches for all changes, the worktree gate must apply to ALL file-producing work — including docs. Make this explicit in routing.md Rules. + +4. **Assuming the coordinator remembers verbal instructions.** Each session starts fresh. If you told the coordinator "always use opus" in session 1, session 2 won't know unless it's in decisions.md or routing.md. + +5. **Not creating `issue-lifecycle.md`.** The framework references it but doesn't create it. If your project uses GitHub Issues Mode, create this template. + +6. **Capturing a decision but never encoding it as a rule.** `decisions.md` is a historical record. The coordinator reads it for context but doesn't treat entries as enforceable constraints. If a decision should be enforced, it must become a numbered rule in `routing.md` Rules section. + +--- + +## Decisions Audit + +Periodically scan `decisions.md` for directives that should be routing rules but aren't: + +1. Search for phrases like "always", "never", "must", "every", "required" +2. For each match, ask: "Is this enforced by a numbered rule in routing.md?" +3. If no → either add a rule, or accept that it's advisory-only +4. If yes → verify the rule text matches the decision + +This prevents `decisions.md` from becoming a graveyard of good intentions that the coordinator reads but doesn't act on. + +--- + +## Appendices + +For detailed end-to-end walkthroughs of specific wiring scenarios, see: + +- **[Appendix A: Wiring a Code Reviewer](workflow-wiring-appendix-a-code-reviewer.md)** — Full walkthrough of adding a code reviewer member and wiring their gate so it actually gets enforced. Includes every file that needs modification with exact content. + +- **[Appendix B: Wiring a Documenter/Librarian](workflow-wiring-appendix-b-documenter.md)** — Full walkthrough of adding a documenter role that ensures all significant changes are documented. Shows a follow-up trigger pattern rather than a gate pattern. diff --git a/packages/squad-sdk/templates/workflows/squad-heartbeat.yml b/packages/squad-sdk/templates/workflows/squad-heartbeat.yml index 1b75fda3e..5494296fd 100644 --- a/packages/squad-sdk/templates/workflows/squad-heartbeat.yml +++ b/packages/squad-sdk/templates/workflows/squad-heartbeat.yml @@ -1,167 +1,167 @@ -name: Squad Heartbeat (Ralph) -# ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all: -# - templates/workflows/squad-heartbeat.yml (source template) -# - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package) -# - .squad/templates/workflows/squad-heartbeat.yml (installed template) -# - .github/workflows/squad-heartbeat.yml (active workflow) -# Run 'squad upgrade' to sync installed copies from source templates. - -on: - # React to completed work or new squad work - issues: - types: [closed, labeled] - pull_request: - types: [closed] - - # Manual trigger - workflow_dispatch: - -permissions: - issues: write - contents: read - pull-requests: read - -jobs: - heartbeat: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Check triage script - id: check-script - run: | - if [ -f ".squad/templates/ralph-triage.js" ]; then - echo "has_script=true" >> $GITHUB_OUTPUT - else - echo "has_script=false" >> $GITHUB_OUTPUT - echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install" - fi - - - name: Ralph — Smart triage - if: steps.check-script.outputs.has_script == 'true' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node .squad/templates/ralph-triage.js \ - --squad-dir .squad \ - --output triage-results.json - - - name: Ralph — Apply triage decisions - if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != '' - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const path = 'triage-results.json'; - if (!fs.existsSync(path)) { - core.info('No triage results — board is clear'); - return; - } - - const results = JSON.parse(fs.readFileSync(path, 'utf8')); - if (results.length === 0) { - core.info('📋 Board is clear — Ralph found no untriaged issues'); - return; - } - - for (const decision of results) { - try { - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: decision.issueNumber, - labels: [decision.label] - }); - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: decision.issueNumber, - body: [ - '### 🔄 Ralph — Auto-Triage', - '', - `**Assigned to:** ${decision.assignTo}`, - `**Reason:** ${decision.reason}`, - `**Source:** ${decision.source}`, - '', - '> Ralph auto-triaged this issue using routing rules.', - '> To reassign, swap the `squad:*` label.' - ].join('\n') - }); - - core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`); - } catch (e) { - core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`); - } - } - - core.info(`🔄 Ralph triaged ${results.length} issue(s)`); - - # Copilot auto-assign step (uses PAT if available) - - name: Ralph — Assign @copilot issues - if: success() - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const fs = require('fs'); - - let teamFile = '.squad/team.md'; - if (!fs.existsSync(teamFile)) { - teamFile = '.ai-team/team.md'; - } - if (!fs.existsSync(teamFile)) return; - - const content = fs.readFileSync(teamFile, 'utf8'); - - // Check if @copilot is on the team with auto-assign - const hasCopilot = content.includes('🤖 Coding Agent') || content.includes('@copilot'); - const autoAssign = content.includes(''); - if (!hasCopilot || !autoAssign) return; - - // Find issues labeled squad:copilot with no assignee - try { - const { data: copilotIssues } = await github.rest.issues.listForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - labels: 'squad:copilot', - state: 'open', - per_page: 5 - }); - - const unassigned = copilotIssues.filter(i => - !i.assignees || i.assignees.length === 0 - ); - - if (unassigned.length === 0) { - core.info('No unassigned squad:copilot issues'); - return; - } - - // Get repo default branch - const { data: repoData } = await github.rest.repos.get({ - owner: context.repo.owner, - repo: context.repo.repo - }); - - for (const issue of unassigned) { - try { - await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue.number, - assignees: ['copilot-swe-agent[bot]'], - agent_assignment: { - target_repo: `${context.repo.owner}/${context.repo.repo}`, - base_branch: repoData.default_branch, - custom_instructions: `Read .squad/team.md (or .ai-team/team.md) for team context and .squad/routing.md (or .ai-team/routing.md) for routing rules.` - } - }); - core.info(`Assigned copilot-swe-agent[bot] to #${issue.number}`); - } catch (e) { - core.warning(`Failed to assign @copilot to #${issue.number}: ${e.message}`); - } - } - } catch (e) { - core.info(`No squad:copilot label found or error: ${e.message}`); - } +name: Squad Heartbeat (Ralph) +# ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all: +# - templates/workflows/squad-heartbeat.yml (source template) +# - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package) +# - .squad/templates/workflows/squad-heartbeat.yml (installed template) +# - .github/workflows/squad-heartbeat.yml (active workflow) +# Run 'squad upgrade' to sync installed copies from source templates. + +on: + # React to completed work or new squad work + issues: + types: [closed, labeled] + pull_request: + types: [closed] + + # Manual trigger + workflow_dispatch: + +permissions: + issues: write + contents: read + pull-requests: read + +jobs: + heartbeat: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check triage script + id: check-script + run: | + if [ -f ".squad/templates/ralph-triage.js" ]; then + echo "has_script=true" >> $GITHUB_OUTPUT + else + echo "has_script=false" >> $GITHUB_OUTPUT + echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install" + fi + + - name: Ralph — Smart triage + if: steps.check-script.outputs.has_script == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + node .squad/templates/ralph-triage.js \ + --squad-dir .squad \ + --output triage-results.json + + - name: Ralph — Apply triage decisions + if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != '' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = 'triage-results.json'; + if (!fs.existsSync(path)) { + core.info('No triage results — board is clear'); + return; + } + + const results = JSON.parse(fs.readFileSync(path, 'utf8')); + if (results.length === 0) { + core.info('📋 Board is clear — Ralph found no untriaged issues'); + return; + } + + for (const decision of results) { + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: decision.issueNumber, + labels: [decision.label] + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: decision.issueNumber, + body: [ + '### 🔄 Ralph — Auto-Triage', + '', + `**Assigned to:** ${decision.assignTo}`, + `**Reason:** ${decision.reason}`, + `**Source:** ${decision.source}`, + '', + '> Ralph auto-triaged this issue using routing rules.', + '> To reassign, swap the `squad:*` label.' + ].join('\n') + }); + + core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`); + } catch (e) { + core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`); + } + } + + core.info(`🔄 Ralph triaged ${results.length} issue(s)`); + + # Copilot auto-assign step (uses PAT if available) + - name: Ralph — Assign @copilot issues + if: success() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + + let teamFile = '.squad/team.md'; + if (!fs.existsSync(teamFile)) { + teamFile = '.ai-team/team.md'; + } + if (!fs.existsSync(teamFile)) return; + + const content = fs.readFileSync(teamFile, 'utf8'); + + // Check if @copilot is on the team with auto-assign + const hasCopilot = content.includes('🤖 Coding Agent') || content.includes('@copilot'); + const autoAssign = content.includes(''); + if (!hasCopilot || !autoAssign) return; + + // Find issues labeled squad:copilot with no assignee + try { + const { data: copilotIssues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + labels: 'squad:copilot', + state: 'open', + per_page: 5 + }); + + const unassigned = copilotIssues.filter(i => + !i.assignees || i.assignees.length === 0 + ); + + if (unassigned.length === 0) { + core.info('No unassigned squad:copilot issues'); + return; + } + + // Get repo default branch + const { data: repoData } = await github.rest.repos.get({ + owner: context.repo.owner, + repo: context.repo.repo + }); + + for (const issue of unassigned) { + try { + await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + assignees: ['copilot-swe-agent[bot]'], + agent_assignment: { + target_repo: `${context.repo.owner}/${context.repo.repo}`, + base_branch: repoData.default_branch, + custom_instructions: `Read .squad/team.md (or .ai-team/team.md) for team context and .squad/routing.md (or .ai-team/routing.md) for routing rules.` + } + }); + core.info(`Assigned copilot-swe-agent[bot] to #${issue.number}`); + } catch (e) { + core.warning(`Failed to assign @copilot to #${issue.number}: ${e.message}`); + } + } + } catch (e) { + core.info(`No squad:copilot label found or error: ${e.message}`); + } diff --git a/templates/workflow-wiring-appendix-a-code-reviewer.md b/templates/workflow-wiring-appendix-a-code-reviewer.md new file mode 100644 index 000000000..c447f7f9c --- /dev/null +++ b/templates/workflow-wiring-appendix-a-code-reviewer.md @@ -0,0 +1,131 @@ +# Appendix A: Wiring a Code Reviewer — Complete Walkthrough + +> End-to-end example of adding a code reviewer to your squad and wiring their gate so it actually gets enforced. This walkthrough addresses a common failure: a reviewer is on the roster but never reviews a single PR because the gate wasn't wired. + +## The Problem This Solves + +Adding a reviewer to `team.md` gives them an identity. It does NOT: +- Tell the coordinator to route PRs to them +- Prevent PRs from being merged without their approval +- Prevent issues from being closed before review happens + +**What goes wrong without enforcement:** A reviewer can be on the roster as "Reviewer" from day one. Their charter says they review PRs. The routing table says "PR code review → {ReviewerName}." But PRs get merged and issues get closed without them ever being spawned. Why? + +Because the routing table says WHO handles what — it's for incoming requests ("review PR #42"). It does NOT say "after every agent completes work, route their output to {ReviewerName}." The coordinator routes work TO agents, but nothing tells it to route COMPLETED work to a reviewer. The "After Agent Work" flow in `squad.agent.md` says: collect results → present → spawn Scribe. No review step. + +**The fix has three layers:** + +| Layer | What it does | Where it lives | +|-------|-------------|----------------| +| Identity | Reviewer exists and knows how to review | `team.md` roster + `charter.md` | +| Routing | User can explicitly request "review this" | `routing.md` routing table | +| **Enforcement** | Coordinator MUST route every PR to reviewer before merge | `routing.md` Rules section + `issue-lifecycle.md` post-work steps | + +Most squads get layers 1 and 2 right. Layer 3 — enforcement — is what's usually missing. + +## Step-by-Step Walkthrough + +### Step 1: Create the reviewer's identity + +Create `.squad/agents/{name}/charter.md`: + +```markdown +# {Name} — Code Reviewer + +## Identity +- **Name:** {Name} +- **Role:** Code Reviewer +- **Expertise:** Code quality, correctness, test coverage, security, patterns +- **Style:** Thorough, fair, specific. Provides actionable feedback. + +## What I Own +- Reviewing PRs for code quality, correctness, and test coverage +- Identifying bugs, security issues, and design problems +- Providing specific, actionable feedback (not vague suggestions) + +## How I Review +1. Read the PR diff completely +2. Check: does it do what the issue asked for? +3. Check: are there tests? Do they cover the important cases? +4. Check: are there bugs, edge cases, or security issues? +5. Check: does it follow project patterns and conventions? +6. Verdict: APPROVE or REJECT with specific feedback + +## Boundaries +**I handle:** Code review, PR review, quality gates +**I don't handle:** Implementation, design, research, documentation + +## On REJECT +I provide specific feedback: what's wrong, why, and what to do instead. +The original author fixes their work. I re-review after fixes. +``` + +Create `.squad/agents/{name}/history.md` seeded with project context. + +### Step 2: Add to team.md roster + +```markdown +| 👑 {Name} | Code Reviewer | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing table entry + +In `routing.md` → routing table: + +```markdown +| PR code review | 👑 {Name} | — | "Review PR #42", code quality, finding reports | +``` + +**⚠️ This is necessary but NOT sufficient.** This only handles explicit review requests. It does NOT enforce automatic review of every PR. + +### Step 4: Add enforcement rule (THIS IS THE CRITICAL STEP) + +In `routing.md` → `## Rules` section, add a numbered rule: + +```markdown +N. **{Name} PR Gate** — every PR created by any agent MUST be reviewed by {Name} + before merge. The coordinator spawns {Name} (sync) with the PR diff after + the author pushes and creates the PR. On REJECT, the original author addresses + feedback. On APPROVE, the coordinator merges via `gh pr merge`. No PR merges + without {Name}'s approval. +``` + +**Why this works when the routing table alone didn't:** The routing table is for matching incoming work to agents. Rules are behavioral constraints the coordinator must follow AFTER work completes. The rule says "after a PR exists, you MUST do X before proceeding." The routing table says "if someone asks for a review, route to X." + +### Step 5: Wire into issue-lifecycle.md + +In `.squad/templates/issue-lifecycle.md`, the "Coordinator Post-Work Steps" section should reference your reviewer by name: + +```markdown +4. **Route to reviewer.** Spawn {Name} (sync) with the PR diff for code review. +``` + +This is the operational detail — the step-by-step instructions the coordinator follows after an agent completes issue work. The routing rule (Step 4) is the mandate; the lifecycle template is the procedure. + +### Step 6: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 7: Verify + +Ask yourself these questions: + +- [ ] If a clean session coordinator reads `routing.md` Rules, will it know to route PRs to this reviewer? → Check rule N exists. +- [ ] If an agent completes work and pushes a PR, does the coordinator's post-work flow include a review step? → Check `issue-lifecycle.md` step 4. +- [ ] Can the coordinator merge a PR without the reviewer's approval? → The rule should say "No PR merges without {Name}'s approval." +- [ ] Can the coordinator close an issue without a merged PR? → Check the issue closure rule exists. + +If any answer is wrong, you have a gap. + +## What Each File Controls (Summary) + +| File | What it contributes to the reviewer gate | +|------|----------------------------------------| +| `charter.md` | WHO the reviewer is and HOW they review | +| `team.md` | That the reviewer EXISTS on the team | +| `routing.md` routing table | That explicit review requests go to this reviewer | +| `routing.md` Rules section | That the coordinator MUST route EVERY PR to this reviewer (enforcement) | +| `issue-lifecycle.md` | The step-by-step procedure for the post-work review flow | +| `casting/registry.json` | Persistent name tracking | + +**Remove any one of these and the gate has a hole.** The most commonly missed piece is the Rules section entry (Step 4). diff --git a/templates/workflow-wiring-appendix-b-documenter.md b/templates/workflow-wiring-appendix-b-documenter.md new file mode 100644 index 000000000..fb8cd26aa --- /dev/null +++ b/templates/workflow-wiring-appendix-b-documenter.md @@ -0,0 +1,140 @@ +# Appendix B: Wiring a Documenter/Librarian — Complete Walkthrough + +> End-to-end example of adding a documenter role that ensures significant changes are documented. This is a FOLLOW-UP TRIGGER pattern — not a gate (which blocks), but an automatic downstream task that fires after work completes. + +## The Problem This Solves + +Your project has agents building features, fixing bugs, and writing tools. But nobody documents what was built, how to use it, or what changed. Documentation happens only when someone explicitly asks — and by then, the context is lost. + +A documenter/librarian role solves this by automatically evaluating whether completed work needs documentation and producing it if so. + +## Gate vs Follow-Up Trigger + +| Pattern | Blocks work? | When it runs | Example | +|---------|-------------|-------------|---------| +| **Gate** (Appendix A) | Yes — work cannot proceed without approval | Before merge | Code reviewer must approve PR | +| **Follow-up trigger** | No — work proceeds, documentation happens in parallel | After merge | Documenter evaluates if docs are needed | + +A documenter is typically a follow-up trigger, not a gate. You don't want documentation review to block a hotfix from merging. But you DO want documentation to happen automatically after significant changes. + +## Step-by-Step Walkthrough + +### Step 1: Create the documenter's identity + +Create `.squad/agents/{name}/charter.md`: + +```markdown +# {Name} — Documenter + +## Identity +- **Name:** {Name} +- **Role:** Documenter / Librarian +- **Expertise:** Documentation, guides, READMEs, changelogs, knowledge management +- **Style:** Clear, thorough, user-focused. Makes complex things understandable. + +## What I Own +- Evaluating whether completed work needs documentation +- Writing/updating READMEs, guides, and runbooks +- Maintaining a docs index so nothing gets lost +- Summarizing design decisions and architectural changes + +## How I Work +1. Read the PR diff or agent output +2. Assess: does this change user-facing behavior? Add a new feature? Change configuration? +3. If yes: write or update the relevant documentation +4. If no: report "no docs needed" with brief justification + +## Boundaries +**I handle:** Documentation, guides, READMEs, summaries, knowledge management +**I don't handle:** Code implementation, code review, research, operations +``` + +Create `.squad/agents/{name}/history.md` seeded with project context. + +### Step 2: Add to team.md roster + +```markdown +| 📝 {Name} | Documenter | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing table entry + +In `routing.md` → routing table: + +```markdown +| Documentation, reports, summaries | 📝 {Name} | `docs/` | "Write docs for X", "Summarize this", guides, READMEs | +``` + +### Step 4: Add follow-up trigger rule + +In `routing.md` → `## Rules` section, add a numbered rule: + +```markdown +N. **Documentation follow-up** — after any PR is merged that adds or modifies + user-facing features, scripts, tools, or configuration, the coordinator + spawns {Name} (background) to evaluate whether documentation is needed. + {Name} reads the merged PR diff and either writes/updates docs or reports + "no docs needed." This is a follow-up, not a gate — it does not block + the merge. +``` + +**Why a rule and not a ceremony:** Ceremonies are structured multi-participant meetings. This is a single-agent follow-up task. A routing rule is simpler and more appropriate. + +**Why background, not sync:** Documentation doesn't block other work. The documenter runs in parallel with whatever comes next. + +### Step 5: Wire into the coordinator's post-merge flow + +This is the trickiest part. The coordinator's After Agent Work flow doesn't currently have a "post-merge" hook. You wire this through the issue-lifecycle template. + +In `.squad/templates/issue-lifecycle.md`, after the merge step, add: + +```markdown +8. **Documentation follow-up.** After merge, check routing.md Rules for + documentation follow-up rule. If present, spawn the documenter (background) + with the merged PR diff to evaluate whether docs are needed. +``` + +Alternatively, you can wire this as an `after` ceremony in `ceremonies.md`: + +```yaml +- name: "Documentation Check" + when: "after" + condition: "PR merged that adds features, scripts, tools, or config changes" + facilitator: "{DocumenterName}" + participants: ["{DocumenterName}"] + output: "Docs written/updated, or 'no docs needed' with justification" +``` + +### Step 6: Worktree for doc changes + +If the documenter produces files, they need a worktree — docs are files too. The coordinator should: +1. Create a worktree for the doc update (e.g., `squad/{issue}-docs`) +2. The documenter commits and pushes +3. A PR is created for the docs +4. The docs PR goes through the normal review flow (including the code reviewer if you have one) + +This means doc changes also get reviewed. The documenter is not exempt from the review gate. + +### Step 7: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 8: Verify + +- [ ] After a feature PR merges, does the coordinator spawn the documenter? → Check the routing rule exists. +- [ ] Does the documenter get a worktree for their work? → Check the worktree rule covers docs. +- [ ] Do doc changes go through the review gate? → They should — docs are files, files need PRs, PRs need review. +- [ ] Is the follow-up non-blocking? → The documenter should be background, not sync. + +## What Each File Controls (Summary) + +| File | What it contributes | +|------|-------------------| +| `charter.md` | WHO the documenter is and HOW they evaluate | +| `team.md` | That the documenter EXISTS | +| `routing.md` routing table | That explicit doc requests go to this member | +| `routing.md` Rules section | That the coordinator MUST spawn docs evaluation after merges (enforcement) | +| `issue-lifecycle.md` or `ceremonies.md` | The procedural hook: when exactly the follow-up fires | +| `casting/registry.json` | Persistent name tracking | + +**The most commonly missed piece:** The Rules section entry (Step 4). Without it, the documenter only runs when someone explicitly says "write docs for X." The whole point is that it runs automatically. diff --git a/templates/workflow-wiring-guide.md b/templates/workflow-wiring-guide.md new file mode 100644 index 000000000..853a13d0a --- /dev/null +++ b/templates/workflow-wiring-guide.md @@ -0,0 +1,276 @@ +# Squad Workflow Wiring Guide + +> How to wire up new team members, reviewer gates, and custom workflows so they actually get enforced by the coordinator — even in a clean session with no prior memory. + +## Why This Guide Exists + +The Squad framework (`squad.agent.md`) provides generic orchestration primitives. **It does not prescribe a specific workflow.** Your project's workflow — whether that's "all code goes through PRs and reviews" or "just commit to main" — must be wired into project-level configuration files. + +If a workflow rule exists only in someone's memory, in a chat transcript, or in `decisions.md` but NOT in a configuration file the coordinator reads at decision time — **it will not be followed in a clean session.** + +### Why Existing Patterns Aren't Enough + +The Squad framework already has concepts for routing tables, reviewer roles, and ceremonies. But having these concepts does NOT mean they work automatically: + +- **Adding a reviewer to the roster ≠ enforcing reviews.** A reviewer can be on the roster with "Reviewer" as their role and never review a single PR — because no RULE in `routing.md` tells the coordinator to route PRs to them. The roster says WHO exists. Rules say WHAT they enforce. + +- **Capturing a decision ≠ enforcing it.** `decisions.md` may contain "every change must go through a PR" and "only {ReviewerName} closes PRs." These can get buried in a large file that the coordinator reads for context but doesn't treat as enforcement rules. A decision is a historical record. A routing rule is an enforceable constraint. + +- **Describing a lifecycle ≠ wiring it.** `squad.agent.md` describes issue→branch→PR→review→merge. But if the After Agent Work section (the flow the coordinator actually follows after every agent completes) has no push/PR/review step, the lifecycle is described conceptually but never connected to the coordinator's actual decision flow. + +**The pattern that works:** A numbered rule in `routing.md` → Rules section. The coordinator reads this section, treats each rule as a constraint, and follows them. If your workflow isn't a numbered rule, it's a suggestion. + +--- + +## Configuration Surface Area + +The coordinator reads these files to decide how to behave. If your workflow isn't encoded in one of these, it doesn't exist. + +| File | What It Controls | Read When | +|------|-----------------|-----------| +| `routing.md` | WHO handles what, behavioral RULES, reviewer GATES | Every session start, before every routing decision | +| `ceremonies.md` | Auto-triggered ceremonies (before/after work batches) | Before spawning work batches, after completion | +| `templates/issue-lifecycle.md` | Git workflow: push, PR, review, merge, issue closure | When spawning agents for issue-linked work | +| Agent `charter.md` | Per-agent identity, boundaries, behavior | Inlined into every spawn prompt | +| `team.md` | Roster, member capabilities | Session start | +| `decisions.md` | Captured decisions and directives | Read by agents at spawn time | + +### How They Interact + +``` +User request arrives + → Coordinator reads routing.md (WHO handles this?) + → Coordinator checks ceremonies.md (any auto-triggered "before" ceremony?) + → Coordinator reads agent charter.md (inline into spawn prompt) + → If issue-linked: coordinator reads issue-lifecycle.md (add ISSUE CONTEXT to spawn prompt) + → Agent works + → Coordinator follows After Agent Work flow + → Coordinator checks ceremonies.md (any auto-triggered "after" ceremony?) + → Coordinator checks routing.md Rules section (any post-work rules to enforce?) +``` + +**The critical insight:** `routing.md` Rules section and `ceremonies.md` are the two enforcement mechanisms. If a rule isn't in one of these, the coordinator has no way to know about it. + +--- + +## How to Wire Up a New Team Member + +### Step 1: Create the member (files) + +``` +.squad/agents/{name}/ + charter.md ← Identity, role, boundaries, what they own + history.md ← Seeded with project context from team.md +``` + +### Step 2: Add to roster (`team.md`) + +Add a row to the `## Members` table: +``` +| {emoji} {Name} | {Role} | `.squad/agents/{name}/charter.md` | ✅ Active | +``` + +### Step 3: Add routing entry (`routing.md`) + +Add a row to the routing table: +``` +| {Work Type} | {emoji} {Name} | {Output Location} | {Examples} | +``` + +### Step 4: Add issue routing (if applicable) + +Add to the Issue Routing table in `routing.md`: +``` +| squad:{name} | {Description of work} | {emoji} {Name} | +``` + +### Step 5: Add to casting registry + +Update `.squad/casting/registry.json` with the new entry. + +### Step 6: Wire any gates (if this member is a reviewer/gate) + +**This is the step most people miss.** If the new member should review or gate other members' work, you need to wire enforcement. See "How to Wire Up a Reviewer Gate" below. + +--- + +## How to Wire Up a Reviewer Gate + +A reviewer gate means: "Agent X must review Agent Y's output before it proceeds." The framework supports this but does NOT automatically enforce it. You must wire it. + +### Option A: Routing Rule (recommended for simple gates) + +Add to `routing.md` → `## Rules` section: + +```markdown +N. **{GateName} Gate** — Every {output type} from {Author} MUST be reviewed by {ReviewerName} before {next step}. The coordinator routes {Author}'s output to {ReviewerName} (sync spawn), collects the verdict, and only proceeds if approved. On rejection, {Author} revises based on {ReviewerName}'s feedback. +``` + +**Example — reviewer for all PRs:** +```markdown +9. **{ReviewerName} PR Gate** — Every PR created by any agent MUST be reviewed by {ReviewerName} before merge. The coordinator spawns {ReviewerName} (sync) with the PR diff, collects APPROVE/REJECT verdict. On rejection, the original author addresses feedback. +``` + +**Example — design review gate:** +```markdown +10. **{DesignReviewer} Design Gate** — Every design doc produced by the architect MUST be reviewed by {DesignReviewer} before implementation begins. {DesignReviewer} always rejects the first draft on concept/approach. Implementation is BLOCKED until {DesignReviewer} approves. +``` + +**Why this works:** The coordinator reads the Rules section before and after every work batch. Rules are behavioral constraints the coordinator must follow. + +### Option B: Ceremony (recommended for multi-participant gates) + +Add to `ceremonies.md` using the Markdown table format the file uses: + +```markdown +## Design Review + +| Field | Value | +|-------|-------| +| **Trigger** | auto | +| **When** | before | +| **Condition** | task involves implementing a design doc | +| **Facilitator** | {DesignReviewer} | +| **Participants** | Architect, {DesignReviewer} | +| **Time budget** | focused | +| **Enabled** | ✅ yes | + +**Agenda:** +1. Read the design doc +2. Challenge the premise and approach +3. Demand alternatives and evidence +4. Verdict: APPROVE or REJECT +``` + +**Why this works:** The coordinator checks ceremonies.md for `before` ceremonies whose condition matches the current task. If matched, the ceremony runs before work begins. + +### Option A vs Option B + +| Use Case | Use Routing Rule | Use Ceremony | +|----------|-----------------|--------------| +| Simple 1-on-1 review (reviewer → author) | ✅ | Overkill | +| Multi-participant alignment (3+ agents) | Too simple | ✅ | +| Needs structured facilitation | No | ✅ | +| Must run automatically before specific work | Either works | ✅ | +| One-line behavioral constraint | ✅ | Overkill | + +--- + +## How to Wire Up an Issue Lifecycle (Git Workflow) + +This is where you define what happens after an agent completes work on a GitHub issue. The framework references `.squad/templates/issue-lifecycle.md` but does NOT create it — you must create it yourself. + +> **⚠️ This file is required if your project uses GitHub Issues Mode.** Without it, the coordinator has no post-work steps for push/PR/review and will treat agent commit as "done." + +See `.squad/templates/issue-lifecycle.md` for the full template if your project already has one. If not, create it following the pattern below. + +### Step 1: Create `templates/issue-lifecycle.md` + +Create `.squad/templates/issue-lifecycle.md` with your project's git workflow. At minimum it should include: + +- An ISSUE CONTEXT block template (for spawn prompts) +- Coordinator post-work steps (verify push → verify PR → route to reviewer → merge on approval) +- Issue closure rules (PR merge auto-close vs manual close) +- Worktree requirements (if applicable) + +### Step 2: Add enforcement rules to `routing.md` + +Add numbered rules to the `## Rules` section that reference the lifecycle: + +```markdown +N. **Issue lifecycle enforcement** — all issue-linked work follows the lifecycle + in `.squad/templates/issue-lifecycle.md`. The coordinator adds the ISSUE CONTEXT + block to spawn prompts and follows the post-work steps (verify push → verify PR + → route to reviewer → merge on approval). Read `issue-lifecycle.md` before + spawning any agent for issue work. + +N+1. **{ReviewerName} PR Gate** — every PR created by any agent MUST be reviewed + by {ReviewerName} before merge. The coordinator spawns {ReviewerName} (sync) + with the PR diff. On REJECT, the original author addresses feedback. On APPROVE, + the coordinator merges. No PR merges without {ReviewerName}'s approval. + +N+2. **Issue closure restriction** — issues that produced files (code, docs, scripts, + designs, tests) close ONLY via PR merge auto-close ("Closes #N" in PR body). + Never use `gh issue close` for file-producing work. Exception: tracking/strategic + issues and superseded issues may be closed with a comment. + +N+3. **Worktree for all file-producing work** — every task that creates or modifies + files (including documentation) requires a worktree. Exceptions: read-only queries, + Scribe (.squad/ state), pure analysis producing no files. +``` + +### Step 3: Verify your wiring + +After creating both files, run the verification checklist (below) to confirm a clean session coordinator would follow the lifecycle. + +--- + +## How to Wire Up a Custom Workflow Step + +If you need something that isn't a reviewer gate or issue lifecycle — for example, "always run tests before pushing" or "docs must be reviewed by the author before merge" — here's where to put it: + +### If it's a behavioral rule the coordinator should always follow: +→ Add to `routing.md` → `## Rules` section + +### If it should trigger automatically before/after specific work: +→ Add to `ceremonies.md` as a `before` or `after` ceremony + +### If it's something agents should do as part of their work: +→ Add to the agent's `charter.md` under a new section + +### If it's something that applies only to issue-linked work: +→ Add to `templates/issue-lifecycle.md` + +### If it's a team-wide constraint that should be visible to all agents: +→ Capture as a decision in `decisions.md` (via directive or decision inbox) + +--- + +## Verification Checklist + +After wiring any new member, gate, or workflow, verify: + +- [ ] **Clean session test:** Start a new session (no memory). Give a task. Does the coordinator follow the new rule? +- [ ] **File completeness:** Is the rule/gate/workflow encoded in a file the coordinator reads? (routing.md, ceremonies.md, issue-lifecycle.md, charter.md) +- [ ] **No verbal-only rules:** Is there anything the coordinator should do that's only in chat history or your memory? If yes, it will be lost on session restart. +- [ ] **Gate enforcement:** If you added a reviewer gate, does the routing.md Rules section or ceremonies.md explicitly say the coordinator must route to the reviewer? "Having a reviewer on the roster" is not the same as "enforcing that they review." +- [ ] **Issue lifecycle:** If your project uses PRs, does `templates/issue-lifecycle.md` exist? Does routing.md reference it? + +--- + +## Common Mistakes + +1. **Adding a reviewer to the roster but not wiring a gate.** Having a reviewer on the team doesn't mean they review anything. You must add a rule in routing.md that says "route PRs to {ReviewerName}." + +2. **Closing issues via `gh issue close` instead of PR merge.** If your project uses PRs, issue closure should happen via "Closes #N" in the PR body. Wire this in issue-lifecycle.md. + +3. **Writing docs/scripts directly on main.** If your project requires branches for all changes, the worktree gate must apply to ALL file-producing work — including docs. Make this explicit in routing.md Rules. + +4. **Assuming the coordinator remembers verbal instructions.** Each session starts fresh. If you told the coordinator "always use opus" in session 1, session 2 won't know unless it's in decisions.md or routing.md. + +5. **Not creating `issue-lifecycle.md`.** The framework references it but doesn't create it. If your project uses GitHub Issues Mode, create this template. + +6. **Capturing a decision but never encoding it as a rule.** `decisions.md` is a historical record. The coordinator reads it for context but doesn't treat entries as enforceable constraints. If a decision should be enforced, it must become a numbered rule in `routing.md` Rules section. + +--- + +## Decisions Audit + +Periodically scan `decisions.md` for directives that should be routing rules but aren't: + +1. Search for phrases like "always", "never", "must", "every", "required" +2. For each match, ask: "Is this enforced by a numbered rule in routing.md?" +3. If no → either add a rule, or accept that it's advisory-only +4. If yes → verify the rule text matches the decision + +This prevents `decisions.md` from becoming a graveyard of good intentions that the coordinator reads but doesn't act on. + +--- + +## Appendices + +For detailed end-to-end walkthroughs of specific wiring scenarios, see: + +- **[Appendix A: Wiring a Code Reviewer](workflow-wiring-appendix-a-code-reviewer.md)** — Full walkthrough of adding a code reviewer member and wiring their gate so it actually gets enforced. Includes every file that needs modification with exact content. + +- **[Appendix B: Wiring a Documenter/Librarian](workflow-wiring-appendix-b-documenter.md)** — Full walkthrough of adding a documenter role that ensures all significant changes are documented. Shows a follow-up trigger pattern rather than a gate pattern. diff --git a/templates/workflows/squad-heartbeat.yml b/templates/workflows/squad-heartbeat.yml index 1b75fda3e..5494296fd 100644 --- a/templates/workflows/squad-heartbeat.yml +++ b/templates/workflows/squad-heartbeat.yml @@ -1,167 +1,167 @@ -name: Squad Heartbeat (Ralph) -# ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all: -# - templates/workflows/squad-heartbeat.yml (source template) -# - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package) -# - .squad/templates/workflows/squad-heartbeat.yml (installed template) -# - .github/workflows/squad-heartbeat.yml (active workflow) -# Run 'squad upgrade' to sync installed copies from source templates. - -on: - # React to completed work or new squad work - issues: - types: [closed, labeled] - pull_request: - types: [closed] - - # Manual trigger - workflow_dispatch: - -permissions: - issues: write - contents: read - pull-requests: read - -jobs: - heartbeat: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Check triage script - id: check-script - run: | - if [ -f ".squad/templates/ralph-triage.js" ]; then - echo "has_script=true" >> $GITHUB_OUTPUT - else - echo "has_script=false" >> $GITHUB_OUTPUT - echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install" - fi - - - name: Ralph — Smart triage - if: steps.check-script.outputs.has_script == 'true' - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - node .squad/templates/ralph-triage.js \ - --squad-dir .squad \ - --output triage-results.json - - - name: Ralph — Apply triage decisions - if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != '' - uses: actions/github-script@v7 - with: - script: | - const fs = require('fs'); - const path = 'triage-results.json'; - if (!fs.existsSync(path)) { - core.info('No triage results — board is clear'); - return; - } - - const results = JSON.parse(fs.readFileSync(path, 'utf8')); - if (results.length === 0) { - core.info('📋 Board is clear — Ralph found no untriaged issues'); - return; - } - - for (const decision of results) { - try { - await github.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: decision.issueNumber, - labels: [decision.label] - }); - - await github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: decision.issueNumber, - body: [ - '### 🔄 Ralph — Auto-Triage', - '', - `**Assigned to:** ${decision.assignTo}`, - `**Reason:** ${decision.reason}`, - `**Source:** ${decision.source}`, - '', - '> Ralph auto-triaged this issue using routing rules.', - '> To reassign, swap the `squad:*` label.' - ].join('\n') - }); - - core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`); - } catch (e) { - core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`); - } - } - - core.info(`🔄 Ralph triaged ${results.length} issue(s)`); - - # Copilot auto-assign step (uses PAT if available) - - name: Ralph — Assign @copilot issues - if: success() - uses: actions/github-script@v7 - with: - github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN || secrets.GITHUB_TOKEN }} - script: | - const fs = require('fs'); - - let teamFile = '.squad/team.md'; - if (!fs.existsSync(teamFile)) { - teamFile = '.ai-team/team.md'; - } - if (!fs.existsSync(teamFile)) return; - - const content = fs.readFileSync(teamFile, 'utf8'); - - // Check if @copilot is on the team with auto-assign - const hasCopilot = content.includes('🤖 Coding Agent') || content.includes('@copilot'); - const autoAssign = content.includes(''); - if (!hasCopilot || !autoAssign) return; - - // Find issues labeled squad:copilot with no assignee - try { - const { data: copilotIssues } = await github.rest.issues.listForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, - labels: 'squad:copilot', - state: 'open', - per_page: 5 - }); - - const unassigned = copilotIssues.filter(i => - !i.assignees || i.assignees.length === 0 - ); - - if (unassigned.length === 0) { - core.info('No unassigned squad:copilot issues'); - return; - } - - // Get repo default branch - const { data: repoData } = await github.rest.repos.get({ - owner: context.repo.owner, - repo: context.repo.repo - }); - - for (const issue of unassigned) { - try { - await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: issue.number, - assignees: ['copilot-swe-agent[bot]'], - agent_assignment: { - target_repo: `${context.repo.owner}/${context.repo.repo}`, - base_branch: repoData.default_branch, - custom_instructions: `Read .squad/team.md (or .ai-team/team.md) for team context and .squad/routing.md (or .ai-team/routing.md) for routing rules.` - } - }); - core.info(`Assigned copilot-swe-agent[bot] to #${issue.number}`); - } catch (e) { - core.warning(`Failed to assign @copilot to #${issue.number}: ${e.message}`); - } - } - } catch (e) { - core.info(`No squad:copilot label found or error: ${e.message}`); - } +name: Squad Heartbeat (Ralph) +# ⚠️ SYNC: This workflow is maintained in 4 locations. Changes must be applied to all: +# - templates/workflows/squad-heartbeat.yml (source template) +# - packages/squad-cli/templates/workflows/squad-heartbeat.yml (CLI package) +# - .squad/templates/workflows/squad-heartbeat.yml (installed template) +# - .github/workflows/squad-heartbeat.yml (active workflow) +# Run 'squad upgrade' to sync installed copies from source templates. + +on: + # React to completed work or new squad work + issues: + types: [closed, labeled] + pull_request: + types: [closed] + + # Manual trigger + workflow_dispatch: + +permissions: + issues: write + contents: read + pull-requests: read + +jobs: + heartbeat: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Check triage script + id: check-script + run: | + if [ -f ".squad/templates/ralph-triage.js" ]; then + echo "has_script=true" >> $GITHUB_OUTPUT + else + echo "has_script=false" >> $GITHUB_OUTPUT + echo "⚠️ ralph-triage.js not found — run 'squad upgrade' to install" + fi + + - name: Ralph — Smart triage + if: steps.check-script.outputs.has_script == 'true' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + node .squad/templates/ralph-triage.js \ + --squad-dir .squad \ + --output triage-results.json + + - name: Ralph — Apply triage decisions + if: steps.check-script.outputs.has_script == 'true' && hashFiles('triage-results.json') != '' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = 'triage-results.json'; + if (!fs.existsSync(path)) { + core.info('No triage results — board is clear'); + return; + } + + const results = JSON.parse(fs.readFileSync(path, 'utf8')); + if (results.length === 0) { + core.info('📋 Board is clear — Ralph found no untriaged issues'); + return; + } + + for (const decision of results) { + try { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: decision.issueNumber, + labels: [decision.label] + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: decision.issueNumber, + body: [ + '### 🔄 Ralph — Auto-Triage', + '', + `**Assigned to:** ${decision.assignTo}`, + `**Reason:** ${decision.reason}`, + `**Source:** ${decision.source}`, + '', + '> Ralph auto-triaged this issue using routing rules.', + '> To reassign, swap the `squad:*` label.' + ].join('\n') + }); + + core.info(`Triaged #${decision.issueNumber} → ${decision.assignTo} (${decision.source})`); + } catch (e) { + core.warning(`Failed to triage #${decision.issueNumber}: ${e.message}`); + } + } + + core.info(`🔄 Ralph triaged ${results.length} issue(s)`); + + # Copilot auto-assign step (uses PAT if available) + - name: Ralph — Assign @copilot issues + if: success() + uses: actions/github-script@v7 + with: + github-token: ${{ secrets.COPILOT_ASSIGN_TOKEN || secrets.GITHUB_TOKEN }} + script: | + const fs = require('fs'); + + let teamFile = '.squad/team.md'; + if (!fs.existsSync(teamFile)) { + teamFile = '.ai-team/team.md'; + } + if (!fs.existsSync(teamFile)) return; + + const content = fs.readFileSync(teamFile, 'utf8'); + + // Check if @copilot is on the team with auto-assign + const hasCopilot = content.includes('🤖 Coding Agent') || content.includes('@copilot'); + const autoAssign = content.includes(''); + if (!hasCopilot || !autoAssign) return; + + // Find issues labeled squad:copilot with no assignee + try { + const { data: copilotIssues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + labels: 'squad:copilot', + state: 'open', + per_page: 5 + }); + + const unassigned = copilotIssues.filter(i => + !i.assignees || i.assignees.length === 0 + ); + + if (unassigned.length === 0) { + core.info('No unassigned squad:copilot issues'); + return; + } + + // Get repo default branch + const { data: repoData } = await github.rest.repos.get({ + owner: context.repo.owner, + repo: context.repo.repo + }); + + for (const issue of unassigned) { + try { + await github.request('POST /repos/{owner}/{repo}/issues/{issue_number}/assignees', { + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + assignees: ['copilot-swe-agent[bot]'], + agent_assignment: { + target_repo: `${context.repo.owner}/${context.repo.repo}`, + base_branch: repoData.default_branch, + custom_instructions: `Read .squad/team.md (or .ai-team/team.md) for team context and .squad/routing.md (or .ai-team/routing.md) for routing rules.` + } + }); + core.info(`Assigned copilot-swe-agent[bot] to #${issue.number}`); + } catch (e) { + core.warning(`Failed to assign @copilot to #${issue.number}: ${e.message}`); + } + } + } catch (e) { + core.info(`No squad:copilot label found or error: ${e.message}`); + }