From 32b6ec60a29107f25a971f463ce9eeec6e822e75 Mon Sep 17 00:00:00 2001 From: Jose Luis Latorre Millas Date: Sun, 25 Oct 2026 19:30:56 +0100 Subject: [PATCH 1/3] fix(templates): give Scribe one definition Since #2030 Scribe's charter says it only merges accepted decisions, and the coordinator's inline Scribe template matches it. Other shipped surfaces still gave Scribe the old broad job: the after-agent reference (archive hard gate, session and orchestration logs, cross-agent history appends, history summarization), the host coordinator digest, the decision-hygiene watch prompt, the spawn reference (skill extraction), routing, ceremony and model-selection references, several skills and docs. Align all of them with the charter, make the after-agent Scribe prompt identical to the inline template, point size hygiene at `squad nap`, and add cross-surface guard tests so retired duties can't come back. The charter's "Exclusive canonical artifacts" paragraph no longer names a session log or a retrospective as something Scribe creates (all copies, including the gh-aw builtin and its manifest digest). Closes #2321 --- .changeset/scribe-single-definition.md | 6 ++ .github/agents/squad.agent.md | 9 ++- .squad-templates/README.md | 2 +- .squad-templates/after-agent-reference.md | 59 ++++------------ .squad-templates/ceremony-reference.md | 3 +- .squad-templates/model-selection-reference.md | 4 +- .squad-templates/routing.md | 2 +- .squad-templates/scribe-charter.md | 2 +- .../skills/agent-collaboration/SKILL.md | 2 +- .../skills/coordinator-init-mode/SKILL.md | 4 +- .../coordinator-source-of-truth/SKILL.md | 8 +-- .squad-templates/skills/init-mode/SKILL.md | 4 +- .../skills/retro-enforcement/SKILL.md | 2 +- .squad-templates/spawn-reference.md | 8 +-- .squad-templates/squad.agent.md | 9 ++- .../src/content/docs/concepts/architecture.md | 2 +- .../content/docs/concepts/what-is-squad.md | 2 +- docs/src/content/docs/features/memory.md | 10 +-- .../content/docs/get-started/first-session.md | 4 +- docs/src/content/docs/reference/glossary.md | 2 +- .../watch/capabilities/decision-hygiene.ts | 7 +- packages/squad-cli/templates/README.md | 2 +- .../templates/after-agent-reference.md | 59 ++++------------ .../squad-cli/templates/ceremony-reference.md | 3 +- .../templates/model-selection-reference.md | 4 +- packages/squad-cli/templates/routing.md | 2 +- .../squad-cli/templates/scribe-charter.md | 2 +- .../skills/agent-collaboration/SKILL.md | 2 +- .../skills/coordinator-init-mode/SKILL.md | 4 +- .../coordinator-source-of-truth/SKILL.md | 8 +-- .../templates/skills/init-mode/SKILL.md | 4 +- .../skills/retro-enforcement/SKILL.md | 2 +- .../squad-cli/templates/spawn-reference.md | 8 +-- .../templates/squad.agent.md.template | 9 ++- .../src/client/adapters/coordinator.ts | 2 +- packages/squad-sdk/templates/README.md | 2 +- .../templates/after-agent-reference.md | 59 ++++------------ .../squad-sdk/templates/ceremony-reference.md | 3 +- .../templates/model-selection-reference.md | 4 +- packages/squad-sdk/templates/routing.md | 2 +- .../squad-sdk/templates/scribe-charter.md | 2 +- .../skills/agent-collaboration/SKILL.md | 2 +- .../skills/coordinator-init-mode/SKILL.md | 4 +- .../coordinator-source-of-truth/SKILL.md | 8 +-- .../templates/skills/init-mode/SKILL.md | 4 +- .../skills/retro-enforcement/SKILL.md | 2 +- .../squad-sdk/templates/spawn-reference.md | 8 +-- .../templates/squad.agent.md.template | 9 ++- templates/README.md | 2 +- templates/after-agent-reference.md | 59 ++++------------ templates/ceremony-reference.md | 3 +- templates/model-selection-reference.md | 4 +- templates/routing.md | 2 +- templates/scribe-charter.md | 2 +- templates/skills/agent-collaboration/SKILL.md | 2 +- .../skills/coordinator-init-mode/SKILL.md | 4 +- .../coordinator-source-of-truth/SKILL.md | 8 +-- templates/skills/init-mode/SKILL.md | 4 +- templates/skills/retro-enforcement/SKILL.md | 2 +- templates/spawn-reference.md | 8 +-- templates/squad.agent.md.template | 9 ++- test/ci/scribe-template.test.ts | 69 ++++++++++++++++++- test/clients.test.ts | 2 +- workflows/shared/builtins/scribe-charter.md | 2 +- workflows/squad-workflows.manifest.json | 2 +- 65 files changed, 257 insertions(+), 298 deletions(-) create mode 100644 .changeset/scribe-single-definition.md diff --git a/.changeset/scribe-single-definition.md b/.changeset/scribe-single-definition.md new file mode 100644 index 000000000..ecd9f4875 --- /dev/null +++ b/.changeset/scribe-single-definition.md @@ -0,0 +1,6 @@ +--- +"@bradygaster/squad-cli": patch +"@bradygaster/squad-sdk": patch +--- + +Give Scribe one definition. Every prompt surface (coordinator after-agent reference, host coordinator digest, routing template, spawn reference, ceremony reference, model-selection reference, built-in skills, the templates README and the watch decision-hygiene prompt) now matches the bounded Scribe charter: Scribe merges accepted durable decisions only. Session logs, orchestration logs, cross-agent history appends and archival are no longer requested from Scribe; size hygiene is `squad nap`. The charter itself no longer lists a session log or a retrospective among the artifacts Scribe creates. diff --git a/.github/agents/squad.agent.md b/.github/agents/squad.agent.md index 32eab19d8..39c510ac8 100644 --- a/.github/agents/squad.agent.md +++ b/.github/agents/squad.agent.md @@ -125,7 +125,7 @@ requirements remain in `.github/PR_REQUIREMENTS.md`. **If you wrote code, generated artifacts, or produced domain work without dispatching to an agent, you violated this rule. The coordinator ROUTES — it does not BUILD. No exceptions.** -**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. +**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. **Resolve state backend:** Read `.squad/config.json` (at the resolved TEAM_ROOT) and check the `stateBackend` field. Valid values: `"local"` (default), `"orphan"`, `"two-layer"`. Legacy alias: `"worktree"` maps to `"local"`. Deprecated: `"git-notes"` maps to `"two-layer"` with a deprecation warning. Store as `STATE_BACKEND` and pass it into every spawn prompt. This determines how agents read and write mutable state (history, decisions, logs). Static config (charters, team.md, routing.md) always lives on disk regardless of backend. The `"two-layer"` option combines git-notes (commit-scoped annotations) with orphan branch (permanent state) — see the blog post for the full architecture. @@ -201,7 +201,6 @@ For each squad member with assigned issues, note them in the session context. Wh ``` 🔧 Runtime Engineer — error handling in index.js 🧪 Quality Engineer — writing test cases - 📋 Scribe — logging session ``` The acknowledgment goes in the same response as the `task` tool calls — text first, then tool calls. Keep it to 1-2 sentences plus the table. Don't narrate the plan; just show who's working on what. @@ -237,7 +236,7 @@ When spawning agents, include the role emoji in the `description` parameter to m - `name: "lead"`, `description: "🏗️ Lead: Reviewing architecture proposal"` - `name: "runtime-engineer"`, `description: "🔧 Runtime Engineer: Refactoring auth module"` - `name: "quality-engineer"`, `description: "🧪 Quality Engineer: Writing test cases"` -- `name: "scribe"`, `description: "📋 Scribe: Log session & merge decisions"` +- `name: "scribe"`, `description: "📋 Scribe: Merge durable decisions"` The `name` parameter generates the human-readable agent ID shown in the tasks panel — it MUST be the agent's lowercase cast name (e.g., `"runtime-engineer"`, `"quality-engineer"`). Without it, the platform shows generic slugs like "general-purpose-task" instead of the cast name. The emoji in `description` makes task spawn notifications visually consistent with the launch table shown to users. @@ -634,7 +633,7 @@ when needed, and present compact outcomes. Spawn Scribe only when durable decisi merging. Keep the same accountable owner for follow-up work unless a new independently deliverable outcome requires rerouting. -**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules, Scribe spawn template, and follow-up sequence. +**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules and follow-up sequence. Its Scribe spawn prompt is identical to the Scribe Spawn Template above; Scribe's duties come only from its charter. ### Ceremonies @@ -646,7 +645,7 @@ Ceremonies are structured team meetings where agents align before or after work. 1. Before spawning a work batch, check `.squad/ceremonies.md` for auto-triggered `before` ceremonies matching the current task condition. 2. After a batch completes, check for `after` ceremonies. Manual ceremonies run only when the user asks. 3. Spawn the facilitator (sync) using the template in the reference file. Facilitator spawns participants as sub-tasks. -4. For `before`: include ceremony summary in work batch spawn prompts. Spawn Scribe (background) to record. +4. For `before`: include ceremony summary in work batch spawn prompts. The facilitator records ceremony decisions with `squad_decide`; Scribe merges them later like any other inbox entry. 5. **Ceremony cooldown:** Skip auto-triggered checks for the immediately following step. 6. Show: `📋 {CeremonyName} completed — facilitated by {Lead}. Decisions: {count} | Action items: {count}.` diff --git a/.squad-templates/README.md b/.squad-templates/README.md index fc2dce679..b0ad2a3fe 100644 --- a/.squad-templates/README.md +++ b/.squad-templates/README.md @@ -29,7 +29,7 @@ of these — they are NOT loaded on every turn. | `mcp-config.md` | Coordinator | MCP server integration details | | `model-selection-reference.md` | Coordinator | Per-agent model and reasoning-effort selection | | `multi-agent-format.md` | Coordinator | Assembling multi-agent artifact output | -| `orchestration-log.md` | Scribe | Writing per-agent orchestration log entries | +| `orchestration-log.md` | Legacy (no default writer; not Scribe) | Format of per-agent orchestration log entries | | `plugin-marketplace.md` | Coordinator | Plugin marketplace discovery and install flow | | `prd-intake.md` | Coordinator | PRD Mode — ingesting a spec for decomposition | | `ralph-reference.md` | Coordinator | Ralph work-monitor lifecycle and board format | diff --git a/.squad-templates/after-agent-reference.md b/.squad-templates/after-agent-reference.md index 401eaae75..839a6587e 100644 --- a/.squad-templates/after-agent-reference.md +++ b/.squad-templates/after-agent-reference.md @@ -7,9 +7,9 @@ (2) "Server Error Retry Loop" — context overflow after fan-out. Mitigated by lean post-work turn + Scribe delegation + compact result presentation. --> -**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe. That's ALL. No orchestration logs, no decision consolidation, no heavy file I/O. +**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe only when accepted durable decisions need merging. That's ALL. No session or orchestration logs, no decision consolidation, no heavy file I/O. -**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Full details go in orchestration log via Scribe. +**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Do not paste full agent output. Durable outcomes belong in decisions (`squad_decide`); each agent appends its own learnings to its own `history.md`. After each batch of agent work: @@ -22,63 +22,34 @@ After each batch of agent work: 3. **Show compact results:** `{emoji} {Name} — {1-line summary of what they did}` -4. **Spawn Scribe** (background, never wait). Only if agents ran or inbox has files: +4. **Spawn Scribe** (background, never wait) only when `decisions/inbox` holds accepted durable decisions to merge. Scribe's duties come only from its charter (`.squad/agents/scribe/charter.md`). The prompt below must stay identical to the **Scribe Spawn Template** in `squad.agent.md`: ``` agent_type: "general-purpose" model: "claude-haiku-4.5" mode: "background" name: "scribe" -description: "📋 Scribe: Log session & merge decisions" +description: "📋 Scribe: Merge durable decisions" prompt: | You are the Scribe. Read .squad/agents/scribe/charter.md. TEAM ROOT: {team_root} CURRENT_DATETIME: STATE_BACKEND: {state_backend} - SPAWN MANIFEST: {spawn_manifest} - Tasks (in order): - 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, - stop without mutating files or git state. - 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. - Record measurements. - 1. DECISIONS ARCHIVE [HARD GATE]: If decisions.md >= 20480 bytes, archive entries older than 30 days NOW. If >= 51200 bytes, archive entries older than 7 days. Do not skip this step. Follow the ARCHIVAL SAFETY RULES below — they are not optional. - 2. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, - merge entries into `decisions.md` with `squad_state_write`, delete processed inbox - entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body - beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at - `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. - 3. ORCHESTRATION LOG: Write `orchestration-log/{timestamp}-{agent}.md` with `squad_state_write` per agent. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms (e.g. `2026-06-02T21-15-30Z`). - 4. SESSION LOG: Write `log/{timestamp}-{topic}.md` with `squad_state_write`. Brief. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms. - 5. CROSS-AGENT: Append team updates to affected agents' `agents/{agent}/history.md` with `squad_state_append`. - 6. HISTORY SUMMARIZATION [HARD GATE]: If any history.md >= 15360 bytes (15KB), summarize now. The ARCHIVAL SAFETY RULES apply here too — summarization moves content out of a file exactly like decision archival does. - 7. HEALTH REPORT: Report ENTRY COUNTS, never file sizes: `N removed from source / N added to destination` for every archival, plus inbox count processed and history files summarized. Write with `squad_state_write` or `squad_state_append`. - - ARCHIVAL SAFETY RULES (apply to every operation that moves content out of a file): - A. DESTINATION MUST BE TRACKED. Before writing, run `git ls-files --error-unmatch `. - Exit 0 -> proceed. Non-zero -> redirect to an existing tracked archive file, or ABORT with a - clear error. `.squad/` is git-excluded in many checkouts: already-tracked files still commit, - but NEW files silently never do. Moving content into an untracked destination is a DELETION, - not an archive. Never create a new timestamped archive file and assume it will commit. - B. APPEND FIRST, VERIFY, THEN DELETE. Append to the destination. Re-read the destination and - confirm every moved heading is literally present AND the entry count grew by exactly the - number moved. Only then remove from the source. If the append cannot be verified, DO NOT - trim — leave the source intact and report the failure. Losing history is far worse than - leaving a file over its size gate. - C. COUNT ENTRIES, NOT BYTES. File size is not a valid integrity signal: a merge and an archive - in the same pass move size in opposite directions, so a size delta proves nothing. - D. NEVER REPORT A GATE OUTCOME YOU DID NOT MEASURE. "No archival required" must come from an - actual measurement. A gate that reports without measuring is worse than no gate. - E. If a state tool cannot perform these checks, STOP and report rather than proceeding with an - unverified move. - - Runtime state tools own persistence. Never switch branches, push note refs, reset - `.squad/`, or commit mutable squad state from this prompt. - - Never speak to user. ⚠️ End with plain text summary after all tool calls. + 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, stop without mutating files or git state. + 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. Record measurements. + 1. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, merge accepted durable decisions into `decisions.md` with `squad_state_write`, delete processed inbox entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. + 2. VERIFY: Re-read `decisions.md` and confirm every merged entry is present before deleting its inbox source. + 3. GIT COMMIT: Do not commit mutable squad state. If non-state repo files changed, report them for coordinator handling. + + Runtime state tools own persistence. Never switch branches, push note refs, reset `.squad/`, or commit mutable squad state from this prompt. + + Never speak to user. End with plain text summary after all tool calls. ``` +Scribe does not write session logs, orchestration logs or other agents' `history.md`, and it does not archive. Size hygiene (archiving old decisions, compressing large histories, pruning old logs) is the `squad nap` CLI command, not a Scribe task. + 5. **Immediately assess:** Does anything trigger follow-up work? Launch it NOW. 6. **Ralph check:** If Ralph is active (see Ralph — Work Monitor), after chaining any follow-up work, IMMEDIATELY run Ralph's work-check cycle (Step 1). Do NOT stop. Do NOT wait for user input. Ralph keeps the pipeline moving until the board is clear. diff --git a/.squad-templates/ceremony-reference.md b/.squad-templates/ceremony-reference.md index 78995215a..316c3c0ec 100644 --- a/.squad-templates/ceremony-reference.md +++ b/.squad-templates/ceremony-reference.md @@ -56,6 +56,7 @@ RULES: - Follow the agenda in order. - For each agenda item, spawn relevant participants as sub-tasks to gather their input. - Synthesize participant input into clear decisions and action items. +- Record each decision with `squad_decide` (one call per decision) so Scribe can merge it. - Keep to the time budget: {focused|extended}. - Output a structured summary at the end. @@ -73,7 +74,7 @@ TASK CONTEXT: - `all-relevant` → agents routed to the current task - `all-involved` → agents that participated in the completed batch - Named agents → spawn only those specific agents -6. **Scribe integration:** Spawn Scribe (background) at ceremony start to record decisions and action items. +6. **Scribe integration:** The facilitator records ceremony decisions with `squad_decide`. Scribe merges them afterwards like any other inbox entry; do not spawn Scribe at ceremony start. 7. **Output format:** ``` 📋 {CeremonyName} completed — facilitated by {Facilitator}. diff --git a/.squad-templates/model-selection-reference.md b/.squad-templates/model-selection-reference.md index eb8ec3a35..c0dd2e70c 100644 --- a/.squad-templates/model-selection-reference.md +++ b/.squad-templates/model-selection-reference.md @@ -70,7 +70,7 @@ Quality-sensitive work that is not code (architecture, research, verification, r | Copilot SDK Expert | Standard | Technical analysis that often touches code | Deep research → premium | | Designer / Visual | Premium | Vision-capable model required | — (never downgrade — vision is non-negotiable) | | DevRel / Writer | Standard | Language-heavy work benefits from a stronger model | Economy profile → fast | -| Scribe / Logger | Fast | Mechanical file ops | — (never bump Scribe) | +| Scribe | Fast | Mechanical decision merging | — (never bump Scribe) | | Git / Release | Fast | Mechanical ops — changelogs, tags, version bumps | — (never bump mechanical ops) | **Task complexity adjustments** (apply at most ONE — no cascading): @@ -119,7 +119,7 @@ Every spawn acknowledgment names the resolved model, its source and a short rati 🔧 Runtime Engineer ({model} · session) — refactoring auth module — session model inherited by this spawn 🎨 Experience Engineer ({model} · task-auto) — designing color system — visual task needs vision → premium tier -📋 Scribe ({model} · task-auto) — logging session — mechanical task → fast tier +📋 Scribe ({model} · task-auto) — merging decisions — mechanical task → fast tier ⚡ Lead ({model} · config) — reviewing proposal — agentModelOverrides.lead in .squad/config.json 📝 Docs Engineer ({model} · fallback) — updating docs — charter model unavailable; next in fast chain ``` diff --git a/.squad-templates/routing.md b/.squad-templates/routing.md index 1f49325cd..21de7c440 100644 --- a/.squad-templates/routing.md +++ b/.squad-templates/routing.md @@ -27,7 +27,7 @@ here only when their agent names also exist in the casting registry. ## Rules 1. **Eager by default** — spawn all agents who could usefully start work, including anticipatory downstream work. -2. **Scribe always runs** after substantial work, always as `mode: "background"`. Never blocks. +2. **Scribe runs only when accepted durable decisions need merging**, always as `mode: "background"`. Never blocks. 3. **Quick facts → coordinator answers directly.** Don't spawn an agent for "what port does the server run on?" 4. **When two agents could handle it**, pick the one whose domain is the primary concern. 5. **"Team, ..." → fan-out.** Spawn all relevant agents in parallel as `mode: "background"`. diff --git a/.squad-templates/scribe-charter.md b/.squad-templates/scribe-charter.md index 2f3c7fce6..6f303ee99 100644 --- a/.squad-templates/scribe-charter.md +++ b/.squad-templates/scribe-charter.md @@ -23,7 +23,7 @@ records, communications records, hooks, E2E records, or onboarding output. **State backend awareness:** Use runtime state tools for non-local backends, including `squad_state_read`, `squad_state_write`, `squad_state_append`, `squad_state_create_if_absent`, `squad_state_delete`, `squad_state_list`, `squad_state_health`, and `squad_decide`. Never switch state branches, push note refs, reset `.squad/`, or commit mutable state manually. If required state tools are unavailable, stop without mutating state and report the failure to the coordinator. -**Exclusive canonical artifacts:** When exactly one canonical artifact must exist — a retrospective, a session log, a claim marker — create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: +**Exclusive canonical artifacts:** When exactly one canonical artifact must exist, such as a claim marker, create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: - `error: "conflict"` — another Scribe already created the canonical artifact. Do **not** retry as a create and do **not** overwrite. Read the winner's content with `squad_state_read` and append to it if you have something to add. - `error: "uncertainty"` — the outcome is unknown. Do **not** assume success and do **not** write over the key. Stop and report the uncertainty in your final summary. diff --git a/.squad-templates/skills/agent-collaboration/SKILL.md b/.squad-templates/skills/agent-collaboration/SKILL.md index 054463cf8..8c7fb0695 100644 --- a/.squad-templates/skills/agent-collaboration/SKILL.md +++ b/.squad-templates/skills/agent-collaboration/SKILL.md @@ -38,5 +38,5 @@ If you have reviewer authority and reject work: the original author is locked ou ## Anti-Patterns - Don't read all agent charters — you only need your own context + decisions.md - Don't write directly to `.squad/decisions.md` — always use the inbox drop-box -- Don't modify other agents' history.md files — that's Scribe's job +- Don't modify other agents' history.md files — record team-relevant decisions with `squad_decide` instead - Don't assume CWD is the repo root — always use TEAM ROOT diff --git a/.squad-templates/skills/coordinator-init-mode/SKILL.md b/.squad-templates/skills/coordinator-init-mode/SKILL.md index 46585cd42..5351d92f4 100644 --- a/.squad-templates/skills/coordinator-init-mode/SKILL.md +++ b/.squad-templates/skills/coordinator-init-mode/SKILL.md @@ -33,7 +33,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user ⚛️ {CastName2} — Frontend Dev React, UI, components 🔧 {CastName3} — Backend Dev APIs, database, services 🧪 {CastName4} — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive 🛡️ Rai — (background) RAI awareness, content safety 🔍 Fact Checker — (verifier) Verification + Devil's Advocate @@ -73,7 +73,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/.squad-templates/skills/coordinator-source-of-truth/SKILL.md b/.squad-templates/skills/coordinator-source-of-truth/SKILL.md index b6948cb9b..468cb3262 100644 --- a/.squad-templates/skills/coordinator-source-of-truth/SKILL.md +++ b/.squad-templates/skills/coordinator-source-of-truth/SKILL.md @@ -26,10 +26,10 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/casting/registry.json` | **Authoritative name registry.** Persistent agent-to-name mappings. | Squad (Coordinator) | Squad (Coordinator) | | `.squad/casting/history.json` | **Derived / append-only.** Universe usage history and assignment snapshots. | Squad (Coordinator) — append only | Squad (Coordinator) | | `.squad/agents/{name}/charter.md` | **Authoritative agent identity.** Per-agent role and boundaries. | Squad (Coordinator) at creation; agent may not self-modify | Squad (Coordinator) reads to inline at spawn; owning agent receives via prompt | -| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only), Scribe (cross-agent updates, summarization) | Owning agent only | -| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | Scribe | Owning agent (read-only) | -| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Scribe | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Scribe | All agents (read-only) | +| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | +| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | +| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/.squad-templates/skills/init-mode/SKILL.md b/.squad-templates/skills/init-mode/SKILL.md index 5f99e7dab..6623165c9 100644 --- a/.squad-templates/skills/init-mode/SKILL.md +++ b/.squad-templates/skills/init-mode/SKILL.md @@ -36,7 +36,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user ⚛️ Frontend — Frontend Dev React, UI, components 🔧 Backend — Backend Dev APIs, database, services 🧪 Tester — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive ``` @@ -56,7 +56,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/.squad-templates/skills/retro-enforcement/SKILL.md b/.squad-templates/skills/retro-enforcement/SKILL.md index e7d319276..fdf0851cd 100644 --- a/.squad-templates/skills/retro-enforcement/SKILL.md +++ b/.squad-templates/skills/retro-enforcement/SKILL.md @@ -62,7 +62,7 @@ $workQueue = Get-PendingIssues | Sort-Object -Property Priority When `Test-RetroOverdue` returns `$true`: 1. **Do not start any other work** until the retro completes -2. **Spawn the facilitator agent** (Scribe or designated) with retro mode +2. **Spawn the facilitator agent** (the Lead or a designated member, never Scribe) with retro mode 3. **Wait for the log file** to be written to `.squad/log/` 4. **Verify action items** were created as GitHub Issues (not markdown) 5. **Resume normal round** after retro log confirmed diff --git a/.squad-templates/spawn-reference.md b/.squad-templates/spawn-reference.md index ec20f7f82..91d628fb3 100644 --- a/.squad-templates/spawn-reference.md +++ b/.squad-templates/spawn-reference.md @@ -159,7 +159,7 @@ prompt: | AFTER work (BEST-EFFORT — do NOT retry on failure): ⚠️ POST-WORK BUDGET: Spend at most 20 tool calls on post-work steps below. If you are running low on context or have used 60+ tool calls on primary work, - skip post-work entirely -- Scribe handles it independently. + skip post-work entirely and say so in your final summary. 1. APPEND learnings with `squad_state_append` to `agents/{name}/history.md`. Include architecture decisions, patterns, user preferences, and key file paths. Use `` as the entry timestamp. @@ -168,11 +168,11 @@ prompt: | unavailable, use `squad_state_write` to `decisions/inbox/{name}-{brief-slug}.md`. 3. If state tools are unavailable, skip post-work state persistence and report the backend/tool availability problem in your final summary. - 4. SKILL EXTRACTION is handled by Scribe — do NOT attempt it yourself. + 4. Do not write skills during post-work. Mention any reusable pattern in your final summary. ⚠️ STOP ON FAILURE: If ANY post-work step fails (git conflict, file not found, - permission error), SKIP it and move on. Do NOT retry. Scribe handles cleanup - independently. Your primary deliverable is already done — post-work is optional. + permission error), SKIP it and move on. Do NOT retry. Report what you skipped in + your final summary. Your primary deliverable is already done — post-work is optional. ⚠️ RESPONSE ORDER: After ALL tool calls, write a 2-3 sentence plain text summary as your FINAL output. No tool calls after this summary. diff --git a/.squad-templates/squad.agent.md b/.squad-templates/squad.agent.md index 32eab19d8..39c510ac8 100644 --- a/.squad-templates/squad.agent.md +++ b/.squad-templates/squad.agent.md @@ -125,7 +125,7 @@ requirements remain in `.github/PR_REQUIREMENTS.md`. **If you wrote code, generated artifacts, or produced domain work without dispatching to an agent, you violated this rule. The coordinator ROUTES — it does not BUILD. No exceptions.** -**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. +**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. **Resolve state backend:** Read `.squad/config.json` (at the resolved TEAM_ROOT) and check the `stateBackend` field. Valid values: `"local"` (default), `"orphan"`, `"two-layer"`. Legacy alias: `"worktree"` maps to `"local"`. Deprecated: `"git-notes"` maps to `"two-layer"` with a deprecation warning. Store as `STATE_BACKEND` and pass it into every spawn prompt. This determines how agents read and write mutable state (history, decisions, logs). Static config (charters, team.md, routing.md) always lives on disk regardless of backend. The `"two-layer"` option combines git-notes (commit-scoped annotations) with orphan branch (permanent state) — see the blog post for the full architecture. @@ -201,7 +201,6 @@ For each squad member with assigned issues, note them in the session context. Wh ``` 🔧 Runtime Engineer — error handling in index.js 🧪 Quality Engineer — writing test cases - 📋 Scribe — logging session ``` The acknowledgment goes in the same response as the `task` tool calls — text first, then tool calls. Keep it to 1-2 sentences plus the table. Don't narrate the plan; just show who's working on what. @@ -237,7 +236,7 @@ When spawning agents, include the role emoji in the `description` parameter to m - `name: "lead"`, `description: "🏗️ Lead: Reviewing architecture proposal"` - `name: "runtime-engineer"`, `description: "🔧 Runtime Engineer: Refactoring auth module"` - `name: "quality-engineer"`, `description: "🧪 Quality Engineer: Writing test cases"` -- `name: "scribe"`, `description: "📋 Scribe: Log session & merge decisions"` +- `name: "scribe"`, `description: "📋 Scribe: Merge durable decisions"` The `name` parameter generates the human-readable agent ID shown in the tasks panel — it MUST be the agent's lowercase cast name (e.g., `"runtime-engineer"`, `"quality-engineer"`). Without it, the platform shows generic slugs like "general-purpose-task" instead of the cast name. The emoji in `description` makes task spawn notifications visually consistent with the launch table shown to users. @@ -634,7 +633,7 @@ when needed, and present compact outcomes. Spawn Scribe only when durable decisi merging. Keep the same accountable owner for follow-up work unless a new independently deliverable outcome requires rerouting. -**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules, Scribe spawn template, and follow-up sequence. +**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules and follow-up sequence. Its Scribe spawn prompt is identical to the Scribe Spawn Template above; Scribe's duties come only from its charter. ### Ceremonies @@ -646,7 +645,7 @@ Ceremonies are structured team meetings where agents align before or after work. 1. Before spawning a work batch, check `.squad/ceremonies.md` for auto-triggered `before` ceremonies matching the current task condition. 2. After a batch completes, check for `after` ceremonies. Manual ceremonies run only when the user asks. 3. Spawn the facilitator (sync) using the template in the reference file. Facilitator spawns participants as sub-tasks. -4. For `before`: include ceremony summary in work batch spawn prompts. Spawn Scribe (background) to record. +4. For `before`: include ceremony summary in work batch spawn prompts. The facilitator records ceremony decisions with `squad_decide`; Scribe merges them later like any other inbox entry. 5. **Ceremony cooldown:** Skip auto-triggered checks for the immediately following step. 6. Show: `📋 {CeremonyName} completed — facilitated by {Lead}. Decisions: {count} | Action items: {count}.` diff --git a/docs/src/content/docs/concepts/architecture.md b/docs/src/content/docs/concepts/architecture.md index 54eaa1298..a225c2cbb 100644 --- a/docs/src/content/docs/concepts/architecture.md +++ b/docs/src/content/docs/concepts/architecture.md @@ -28,7 +28,7 @@ All team state lives in `.squad/`. This includes the roster (`team.md`), routing ### Routing Routing rules in `.squad/routing.md` define which agent handles which work. The coordinator reads these rules before spawning. You can override routing by naming an agent directly in your request. ### Scribe -The Scribe is a silent agent that tracks decisions and logs sessions. Every team has a Scribe. You never talk to them directly — they work in the background, merging decisions from all agents into `.squad/decisions.md`. +The Scribe is a silent agent that merges accepted decisions. It does not write session logs or agent histories. Every team has a Scribe. You never talk to them directly — they work in the background, merging decisions from all agents into `.squad/decisions.md`. ### Ralph Ralph is the work monitor. He watches your GitHub or GitLab issues, tracks work in progress, and alerts the team when something is ready. Every team has a Ralph. He's silent unless you ask him for status. diff --git a/docs/src/content/docs/concepts/what-is-squad.md b/docs/src/content/docs/concepts/what-is-squad.md index bd7b909de..ddd4a9348 100644 --- a/docs/src/content/docs/concepts/what-is-squad.md +++ b/docs/src/content/docs/concepts/what-is-squad.md @@ -87,7 +87,7 @@ Routing rules in `.squad/routing.md` define which agent handles which category o ### Scribe -The Scribe is a silent agent that tracks decisions and logs sessions. Every team includes a Scribe. The Scribe runs in the background and merges decisions from all agents into `.squad/decisions.md`. You don't address the Scribe directly. +The Scribe is a silent agent that merges accepted decisions. It does not write session logs or agent histories. Every team includes a Scribe. The Scribe runs in the background and merges decisions from all agents into `.squad/decisions.md`. You don't address the Scribe directly. ### Ralph diff --git a/docs/src/content/docs/features/memory.md b/docs/src/content/docs/features/memory.md index 15c4a7ef9..09aeac4a2 100644 --- a/docs/src/content/docs/features/memory.md +++ b/docs/src/content/docs/features/memory.md @@ -165,16 +165,18 @@ These go directly into `decisions.md`. ### 3. Scribe merges -The Scribe agent (a silent team member) periodically: +The Scribe agent (a silent team member), when accepted decisions are waiting: 1. Reads all entries from `.squad/decisions/inbox/` 2. Merges them into the canonical `decisions.md` -3. Deduplicates overlapping decisions -4. Propagates updates to affected agents +3. Deduplicates exact duplicate decision headings +4. Deletes each inbox entry only after confirming it was merged + +Scribe does not archive, write session logs, or edit agent histories. ### Decision archiving -As your project grows, `decisions.md` accumulates hundreds of blocks. Stale sprint artifacts, completed analysis docs, and one-time planning fragments consume context window space without adding value. When this happens, old decisions are archived to `.squad/decisions-archive.md` — preserved for reference but no longer loaded into agent context. +As your project grows, `decisions.md` accumulates hundreds of blocks. Stale sprint artifacts, completed analysis docs, and one-time planning fragments consume context window space without adding value. When this happens, run `squad nap` to archive old decisions to `.squad/decisions-archive.md` — preserved for reference but no longer loaded into agent context. Active decisions (ongoing policies, user preferences, current architecture) stay in `decisions.md`. Agents always read the lean, current shared brain. diff --git a/docs/src/content/docs/get-started/first-session.md b/docs/src/content/docs/get-started/first-session.md index 447e0a983..46f530409 100644 --- a/docs/src/content/docs/get-started/first-session.md +++ b/docs/src/content/docs/get-started/first-session.md @@ -47,7 +47,7 @@ Here's your team: ⚛️ Ripley — Frontend Dev React, UI, components 🔧 Dallas — Backend Dev Node.js, APIs, database 🧪 Lambert — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging **Scribe** and **Ralph** are always on every roster — you don't manage them. Look right? Say yes, add someone, or change a role. (Or just give me a task to start!) @@ -121,7 +121,7 @@ When agents finish, you see results tagged with each agent's identity: - Detail endpoint returns 404 for missing recipe [+4 more] ``` -Behind the scenes, the Scribe merged decisions from each agent into `decisions.md` and logged the session. +Behind the scenes, the Scribe merged the accepted decisions from each agent into `decisions.md`. --- ## 6. Ask "Where Are We?" — Instant Status diff --git a/docs/src/content/docs/reference/glossary.md b/docs/src/content/docs/reference/glossary.md index b1cf7e7e0..db4312666 100644 --- a/docs/src/content/docs/reference/glossary.md +++ b/docs/src/content/docs/reference/glossary.md @@ -24,7 +24,7 @@ Key terms defined in one sentence each. Alphabetical order. **Routing** — Rules in `.squad/routing.md` that define which agent handles which type of work, read by the coordinator before spawning. -**Scribe** — The silent agent that tracks decisions and logs sessions, merging proposals from all agents into `.squad/decisions.md`. +**Scribe** — The silent built-in agent that merges accepted decisions from `.squad/decisions/inbox/` into `.squad/decisions.md`. It does not write session logs or agent histories. **Skill** — A reusable capability stored in `.copilot/skills/` that agents can learn and execute. diff --git a/packages/squad-cli/src/cli/commands/watch/capabilities/decision-hygiene.ts b/packages/squad-cli/src/cli/commands/watch/capabilities/decision-hygiene.ts index c582df855..591b148be 100644 --- a/packages/squad-cli/src/cli/commands/watch/capabilities/decision-hygiene.ts +++ b/packages/squad-cli/src/cli/commands/watch/capabilities/decision-hygiene.ts @@ -44,15 +44,16 @@ export class DecisionHygieneCapability implements WatchCapability { } const prompt = + 'You are the Scribe. Read .squad/agents/scribe/charter.md and follow it; it alone defines your duties. ' + + `TEAM ROOT: ${context.teamRoot}. ` + 'Merge the decision inbox files in .squad/decisions/inbox/ into .squad/decisions.md. ' + 'Append each decision as a new section. ' + 'Before splicing an inbox body beneath an "###" entry, DEMOTE its headings so the ' + 'shallowest heading lands at "####" — never leave an "##" under an "###". Be ' + 'fence-aware: "#" lines inside fenced code blocks are comments, not headings. ' + 'Delete an inbox file only after confirming its content is literally present in ' + - 'decisions.md. If you archive anything out of decisions.md: verify the destination is ' + - 'git-tracked first (git ls-files --error-unmatch), append and verify before trimming, ' + - 'and report entry counts moved rather than file sizes.'; + 'decisions.md. Do not archive, write logs or edit agent histories: size hygiene is ' + + 'the `squad nap` CLI command.'; const { cmd, args, checkStdout } = buildAgentCommand(prompt, context); await spawnWithTimeout(cmd, args, context.teamRoot, 60_000, checkStdout); diff --git a/packages/squad-cli/templates/README.md b/packages/squad-cli/templates/README.md index fc2dce679..b0ad2a3fe 100644 --- a/packages/squad-cli/templates/README.md +++ b/packages/squad-cli/templates/README.md @@ -29,7 +29,7 @@ of these — they are NOT loaded on every turn. | `mcp-config.md` | Coordinator | MCP server integration details | | `model-selection-reference.md` | Coordinator | Per-agent model and reasoning-effort selection | | `multi-agent-format.md` | Coordinator | Assembling multi-agent artifact output | -| `orchestration-log.md` | Scribe | Writing per-agent orchestration log entries | +| `orchestration-log.md` | Legacy (no default writer; not Scribe) | Format of per-agent orchestration log entries | | `plugin-marketplace.md` | Coordinator | Plugin marketplace discovery and install flow | | `prd-intake.md` | Coordinator | PRD Mode — ingesting a spec for decomposition | | `ralph-reference.md` | Coordinator | Ralph work-monitor lifecycle and board format | diff --git a/packages/squad-cli/templates/after-agent-reference.md b/packages/squad-cli/templates/after-agent-reference.md index 401eaae75..839a6587e 100644 --- a/packages/squad-cli/templates/after-agent-reference.md +++ b/packages/squad-cli/templates/after-agent-reference.md @@ -7,9 +7,9 @@ (2) "Server Error Retry Loop" — context overflow after fan-out. Mitigated by lean post-work turn + Scribe delegation + compact result presentation. --> -**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe. That's ALL. No orchestration logs, no decision consolidation, no heavy file I/O. +**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe only when accepted durable decisions need merging. That's ALL. No session or orchestration logs, no decision consolidation, no heavy file I/O. -**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Full details go in orchestration log via Scribe. +**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Do not paste full agent output. Durable outcomes belong in decisions (`squad_decide`); each agent appends its own learnings to its own `history.md`. After each batch of agent work: @@ -22,63 +22,34 @@ After each batch of agent work: 3. **Show compact results:** `{emoji} {Name} — {1-line summary of what they did}` -4. **Spawn Scribe** (background, never wait). Only if agents ran or inbox has files: +4. **Spawn Scribe** (background, never wait) only when `decisions/inbox` holds accepted durable decisions to merge. Scribe's duties come only from its charter (`.squad/agents/scribe/charter.md`). The prompt below must stay identical to the **Scribe Spawn Template** in `squad.agent.md`: ``` agent_type: "general-purpose" model: "claude-haiku-4.5" mode: "background" name: "scribe" -description: "📋 Scribe: Log session & merge decisions" +description: "📋 Scribe: Merge durable decisions" prompt: | You are the Scribe. Read .squad/agents/scribe/charter.md. TEAM ROOT: {team_root} CURRENT_DATETIME: STATE_BACKEND: {state_backend} - SPAWN MANIFEST: {spawn_manifest} - Tasks (in order): - 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, - stop without mutating files or git state. - 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. - Record measurements. - 1. DECISIONS ARCHIVE [HARD GATE]: If decisions.md >= 20480 bytes, archive entries older than 30 days NOW. If >= 51200 bytes, archive entries older than 7 days. Do not skip this step. Follow the ARCHIVAL SAFETY RULES below — they are not optional. - 2. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, - merge entries into `decisions.md` with `squad_state_write`, delete processed inbox - entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body - beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at - `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. - 3. ORCHESTRATION LOG: Write `orchestration-log/{timestamp}-{agent}.md` with `squad_state_write` per agent. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms (e.g. `2026-06-02T21-15-30Z`). - 4. SESSION LOG: Write `log/{timestamp}-{topic}.md` with `squad_state_write`. Brief. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms. - 5. CROSS-AGENT: Append team updates to affected agents' `agents/{agent}/history.md` with `squad_state_append`. - 6. HISTORY SUMMARIZATION [HARD GATE]: If any history.md >= 15360 bytes (15KB), summarize now. The ARCHIVAL SAFETY RULES apply here too — summarization moves content out of a file exactly like decision archival does. - 7. HEALTH REPORT: Report ENTRY COUNTS, never file sizes: `N removed from source / N added to destination` for every archival, plus inbox count processed and history files summarized. Write with `squad_state_write` or `squad_state_append`. - - ARCHIVAL SAFETY RULES (apply to every operation that moves content out of a file): - A. DESTINATION MUST BE TRACKED. Before writing, run `git ls-files --error-unmatch `. - Exit 0 -> proceed. Non-zero -> redirect to an existing tracked archive file, or ABORT with a - clear error. `.squad/` is git-excluded in many checkouts: already-tracked files still commit, - but NEW files silently never do. Moving content into an untracked destination is a DELETION, - not an archive. Never create a new timestamped archive file and assume it will commit. - B. APPEND FIRST, VERIFY, THEN DELETE. Append to the destination. Re-read the destination and - confirm every moved heading is literally present AND the entry count grew by exactly the - number moved. Only then remove from the source. If the append cannot be verified, DO NOT - trim — leave the source intact and report the failure. Losing history is far worse than - leaving a file over its size gate. - C. COUNT ENTRIES, NOT BYTES. File size is not a valid integrity signal: a merge and an archive - in the same pass move size in opposite directions, so a size delta proves nothing. - D. NEVER REPORT A GATE OUTCOME YOU DID NOT MEASURE. "No archival required" must come from an - actual measurement. A gate that reports without measuring is worse than no gate. - E. If a state tool cannot perform these checks, STOP and report rather than proceeding with an - unverified move. - - Runtime state tools own persistence. Never switch branches, push note refs, reset - `.squad/`, or commit mutable squad state from this prompt. - - Never speak to user. ⚠️ End with plain text summary after all tool calls. + 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, stop without mutating files or git state. + 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. Record measurements. + 1. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, merge accepted durable decisions into `decisions.md` with `squad_state_write`, delete processed inbox entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. + 2. VERIFY: Re-read `decisions.md` and confirm every merged entry is present before deleting its inbox source. + 3. GIT COMMIT: Do not commit mutable squad state. If non-state repo files changed, report them for coordinator handling. + + Runtime state tools own persistence. Never switch branches, push note refs, reset `.squad/`, or commit mutable squad state from this prompt. + + Never speak to user. End with plain text summary after all tool calls. ``` +Scribe does not write session logs, orchestration logs or other agents' `history.md`, and it does not archive. Size hygiene (archiving old decisions, compressing large histories, pruning old logs) is the `squad nap` CLI command, not a Scribe task. + 5. **Immediately assess:** Does anything trigger follow-up work? Launch it NOW. 6. **Ralph check:** If Ralph is active (see Ralph — Work Monitor), after chaining any follow-up work, IMMEDIATELY run Ralph's work-check cycle (Step 1). Do NOT stop. Do NOT wait for user input. Ralph keeps the pipeline moving until the board is clear. diff --git a/packages/squad-cli/templates/ceremony-reference.md b/packages/squad-cli/templates/ceremony-reference.md index 78995215a..316c3c0ec 100644 --- a/packages/squad-cli/templates/ceremony-reference.md +++ b/packages/squad-cli/templates/ceremony-reference.md @@ -56,6 +56,7 @@ RULES: - Follow the agenda in order. - For each agenda item, spawn relevant participants as sub-tasks to gather their input. - Synthesize participant input into clear decisions and action items. +- Record each decision with `squad_decide` (one call per decision) so Scribe can merge it. - Keep to the time budget: {focused|extended}. - Output a structured summary at the end. @@ -73,7 +74,7 @@ TASK CONTEXT: - `all-relevant` → agents routed to the current task - `all-involved` → agents that participated in the completed batch - Named agents → spawn only those specific agents -6. **Scribe integration:** Spawn Scribe (background) at ceremony start to record decisions and action items. +6. **Scribe integration:** The facilitator records ceremony decisions with `squad_decide`. Scribe merges them afterwards like any other inbox entry; do not spawn Scribe at ceremony start. 7. **Output format:** ``` 📋 {CeremonyName} completed — facilitated by {Facilitator}. diff --git a/packages/squad-cli/templates/model-selection-reference.md b/packages/squad-cli/templates/model-selection-reference.md index eb8ec3a35..c0dd2e70c 100644 --- a/packages/squad-cli/templates/model-selection-reference.md +++ b/packages/squad-cli/templates/model-selection-reference.md @@ -70,7 +70,7 @@ Quality-sensitive work that is not code (architecture, research, verification, r | Copilot SDK Expert | Standard | Technical analysis that often touches code | Deep research → premium | | Designer / Visual | Premium | Vision-capable model required | — (never downgrade — vision is non-negotiable) | | DevRel / Writer | Standard | Language-heavy work benefits from a stronger model | Economy profile → fast | -| Scribe / Logger | Fast | Mechanical file ops | — (never bump Scribe) | +| Scribe | Fast | Mechanical decision merging | — (never bump Scribe) | | Git / Release | Fast | Mechanical ops — changelogs, tags, version bumps | — (never bump mechanical ops) | **Task complexity adjustments** (apply at most ONE — no cascading): @@ -119,7 +119,7 @@ Every spawn acknowledgment names the resolved model, its source and a short rati 🔧 Runtime Engineer ({model} · session) — refactoring auth module — session model inherited by this spawn 🎨 Experience Engineer ({model} · task-auto) — designing color system — visual task needs vision → premium tier -📋 Scribe ({model} · task-auto) — logging session — mechanical task → fast tier +📋 Scribe ({model} · task-auto) — merging decisions — mechanical task → fast tier ⚡ Lead ({model} · config) — reviewing proposal — agentModelOverrides.lead in .squad/config.json 📝 Docs Engineer ({model} · fallback) — updating docs — charter model unavailable; next in fast chain ``` diff --git a/packages/squad-cli/templates/routing.md b/packages/squad-cli/templates/routing.md index 1f49325cd..21de7c440 100644 --- a/packages/squad-cli/templates/routing.md +++ b/packages/squad-cli/templates/routing.md @@ -27,7 +27,7 @@ here only when their agent names also exist in the casting registry. ## Rules 1. **Eager by default** — spawn all agents who could usefully start work, including anticipatory downstream work. -2. **Scribe always runs** after substantial work, always as `mode: "background"`. Never blocks. +2. **Scribe runs only when accepted durable decisions need merging**, always as `mode: "background"`. Never blocks. 3. **Quick facts → coordinator answers directly.** Don't spawn an agent for "what port does the server run on?" 4. **When two agents could handle it**, pick the one whose domain is the primary concern. 5. **"Team, ..." → fan-out.** Spawn all relevant agents in parallel as `mode: "background"`. diff --git a/packages/squad-cli/templates/scribe-charter.md b/packages/squad-cli/templates/scribe-charter.md index 2f3c7fce6..6f303ee99 100644 --- a/packages/squad-cli/templates/scribe-charter.md +++ b/packages/squad-cli/templates/scribe-charter.md @@ -23,7 +23,7 @@ records, communications records, hooks, E2E records, or onboarding output. **State backend awareness:** Use runtime state tools for non-local backends, including `squad_state_read`, `squad_state_write`, `squad_state_append`, `squad_state_create_if_absent`, `squad_state_delete`, `squad_state_list`, `squad_state_health`, and `squad_decide`. Never switch state branches, push note refs, reset `.squad/`, or commit mutable state manually. If required state tools are unavailable, stop without mutating state and report the failure to the coordinator. -**Exclusive canonical artifacts:** When exactly one canonical artifact must exist — a retrospective, a session log, a claim marker — create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: +**Exclusive canonical artifacts:** When exactly one canonical artifact must exist, such as a claim marker, create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: - `error: "conflict"` — another Scribe already created the canonical artifact. Do **not** retry as a create and do **not** overwrite. Read the winner's content with `squad_state_read` and append to it if you have something to add. - `error: "uncertainty"` — the outcome is unknown. Do **not** assume success and do **not** write over the key. Stop and report the uncertainty in your final summary. diff --git a/packages/squad-cli/templates/skills/agent-collaboration/SKILL.md b/packages/squad-cli/templates/skills/agent-collaboration/SKILL.md index 054463cf8..8c7fb0695 100644 --- a/packages/squad-cli/templates/skills/agent-collaboration/SKILL.md +++ b/packages/squad-cli/templates/skills/agent-collaboration/SKILL.md @@ -38,5 +38,5 @@ If you have reviewer authority and reject work: the original author is locked ou ## Anti-Patterns - Don't read all agent charters — you only need your own context + decisions.md - Don't write directly to `.squad/decisions.md` — always use the inbox drop-box -- Don't modify other agents' history.md files — that's Scribe's job +- Don't modify other agents' history.md files — record team-relevant decisions with `squad_decide` instead - Don't assume CWD is the repo root — always use TEAM ROOT diff --git a/packages/squad-cli/templates/skills/coordinator-init-mode/SKILL.md b/packages/squad-cli/templates/skills/coordinator-init-mode/SKILL.md index 46585cd42..5351d92f4 100644 --- a/packages/squad-cli/templates/skills/coordinator-init-mode/SKILL.md +++ b/packages/squad-cli/templates/skills/coordinator-init-mode/SKILL.md @@ -33,7 +33,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user ⚛️ {CastName2} — Frontend Dev React, UI, components 🔧 {CastName3} — Backend Dev APIs, database, services 🧪 {CastName4} — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive 🛡️ Rai — (background) RAI awareness, content safety 🔍 Fact Checker — (verifier) Verification + Devil's Advocate @@ -73,7 +73,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md b/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md index b6948cb9b..468cb3262 100644 --- a/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md +++ b/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md @@ -26,10 +26,10 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/casting/registry.json` | **Authoritative name registry.** Persistent agent-to-name mappings. | Squad (Coordinator) | Squad (Coordinator) | | `.squad/casting/history.json` | **Derived / append-only.** Universe usage history and assignment snapshots. | Squad (Coordinator) — append only | Squad (Coordinator) | | `.squad/agents/{name}/charter.md` | **Authoritative agent identity.** Per-agent role and boundaries. | Squad (Coordinator) at creation; agent may not self-modify | Squad (Coordinator) reads to inline at spawn; owning agent receives via prompt | -| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only), Scribe (cross-agent updates, summarization) | Owning agent only | -| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | Scribe | Owning agent (read-only) | -| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Scribe | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Scribe | All agents (read-only) | +| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | +| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | +| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/packages/squad-cli/templates/skills/init-mode/SKILL.md b/packages/squad-cli/templates/skills/init-mode/SKILL.md index 5f99e7dab..6623165c9 100644 --- a/packages/squad-cli/templates/skills/init-mode/SKILL.md +++ b/packages/squad-cli/templates/skills/init-mode/SKILL.md @@ -36,7 +36,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user ⚛️ Frontend — Frontend Dev React, UI, components 🔧 Backend — Backend Dev APIs, database, services 🧪 Tester — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive ``` @@ -56,7 +56,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/packages/squad-cli/templates/skills/retro-enforcement/SKILL.md b/packages/squad-cli/templates/skills/retro-enforcement/SKILL.md index e7d319276..fdf0851cd 100644 --- a/packages/squad-cli/templates/skills/retro-enforcement/SKILL.md +++ b/packages/squad-cli/templates/skills/retro-enforcement/SKILL.md @@ -62,7 +62,7 @@ $workQueue = Get-PendingIssues | Sort-Object -Property Priority When `Test-RetroOverdue` returns `$true`: 1. **Do not start any other work** until the retro completes -2. **Spawn the facilitator agent** (Scribe or designated) with retro mode +2. **Spawn the facilitator agent** (the Lead or a designated member, never Scribe) with retro mode 3. **Wait for the log file** to be written to `.squad/log/` 4. **Verify action items** were created as GitHub Issues (not markdown) 5. **Resume normal round** after retro log confirmed diff --git a/packages/squad-cli/templates/spawn-reference.md b/packages/squad-cli/templates/spawn-reference.md index ec20f7f82..91d628fb3 100644 --- a/packages/squad-cli/templates/spawn-reference.md +++ b/packages/squad-cli/templates/spawn-reference.md @@ -159,7 +159,7 @@ prompt: | AFTER work (BEST-EFFORT — do NOT retry on failure): ⚠️ POST-WORK BUDGET: Spend at most 20 tool calls on post-work steps below. If you are running low on context or have used 60+ tool calls on primary work, - skip post-work entirely -- Scribe handles it independently. + skip post-work entirely and say so in your final summary. 1. APPEND learnings with `squad_state_append` to `agents/{name}/history.md`. Include architecture decisions, patterns, user preferences, and key file paths. Use `` as the entry timestamp. @@ -168,11 +168,11 @@ prompt: | unavailable, use `squad_state_write` to `decisions/inbox/{name}-{brief-slug}.md`. 3. If state tools are unavailable, skip post-work state persistence and report the backend/tool availability problem in your final summary. - 4. SKILL EXTRACTION is handled by Scribe — do NOT attempt it yourself. + 4. Do not write skills during post-work. Mention any reusable pattern in your final summary. ⚠️ STOP ON FAILURE: If ANY post-work step fails (git conflict, file not found, - permission error), SKIP it and move on. Do NOT retry. Scribe handles cleanup - independently. Your primary deliverable is already done — post-work is optional. + permission error), SKIP it and move on. Do NOT retry. Report what you skipped in + your final summary. Your primary deliverable is already done — post-work is optional. ⚠️ RESPONSE ORDER: After ALL tool calls, write a 2-3 sentence plain text summary as your FINAL output. No tool calls after this summary. diff --git a/packages/squad-cli/templates/squad.agent.md.template b/packages/squad-cli/templates/squad.agent.md.template index 32eab19d8..39c510ac8 100644 --- a/packages/squad-cli/templates/squad.agent.md.template +++ b/packages/squad-cli/templates/squad.agent.md.template @@ -125,7 +125,7 @@ requirements remain in `.github/PR_REQUIREMENTS.md`. **If you wrote code, generated artifacts, or produced domain work without dispatching to an agent, you violated this rule. The coordinator ROUTES — it does not BUILD. No exceptions.** -**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. +**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. **Resolve state backend:** Read `.squad/config.json` (at the resolved TEAM_ROOT) and check the `stateBackend` field. Valid values: `"local"` (default), `"orphan"`, `"two-layer"`. Legacy alias: `"worktree"` maps to `"local"`. Deprecated: `"git-notes"` maps to `"two-layer"` with a deprecation warning. Store as `STATE_BACKEND` and pass it into every spawn prompt. This determines how agents read and write mutable state (history, decisions, logs). Static config (charters, team.md, routing.md) always lives on disk regardless of backend. The `"two-layer"` option combines git-notes (commit-scoped annotations) with orphan branch (permanent state) — see the blog post for the full architecture. @@ -201,7 +201,6 @@ For each squad member with assigned issues, note them in the session context. Wh ``` 🔧 Runtime Engineer — error handling in index.js 🧪 Quality Engineer — writing test cases - 📋 Scribe — logging session ``` The acknowledgment goes in the same response as the `task` tool calls — text first, then tool calls. Keep it to 1-2 sentences plus the table. Don't narrate the plan; just show who's working on what. @@ -237,7 +236,7 @@ When spawning agents, include the role emoji in the `description` parameter to m - `name: "lead"`, `description: "🏗️ Lead: Reviewing architecture proposal"` - `name: "runtime-engineer"`, `description: "🔧 Runtime Engineer: Refactoring auth module"` - `name: "quality-engineer"`, `description: "🧪 Quality Engineer: Writing test cases"` -- `name: "scribe"`, `description: "📋 Scribe: Log session & merge decisions"` +- `name: "scribe"`, `description: "📋 Scribe: Merge durable decisions"` The `name` parameter generates the human-readable agent ID shown in the tasks panel — it MUST be the agent's lowercase cast name (e.g., `"runtime-engineer"`, `"quality-engineer"`). Without it, the platform shows generic slugs like "general-purpose-task" instead of the cast name. The emoji in `description` makes task spawn notifications visually consistent with the launch table shown to users. @@ -634,7 +633,7 @@ when needed, and present compact outcomes. Spawn Scribe only when durable decisi merging. Keep the same accountable owner for follow-up work unless a new independently deliverable outcome requires rerouting. -**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules, Scribe spawn template, and follow-up sequence. +**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules and follow-up sequence. Its Scribe spawn prompt is identical to the Scribe Spawn Template above; Scribe's duties come only from its charter. ### Ceremonies @@ -646,7 +645,7 @@ Ceremonies are structured team meetings where agents align before or after work. 1. Before spawning a work batch, check `.squad/ceremonies.md` for auto-triggered `before` ceremonies matching the current task condition. 2. After a batch completes, check for `after` ceremonies. Manual ceremonies run only when the user asks. 3. Spawn the facilitator (sync) using the template in the reference file. Facilitator spawns participants as sub-tasks. -4. For `before`: include ceremony summary in work batch spawn prompts. Spawn Scribe (background) to record. +4. For `before`: include ceremony summary in work batch spawn prompts. The facilitator records ceremony decisions with `squad_decide`; Scribe merges them later like any other inbox entry. 5. **Ceremony cooldown:** Skip auto-triggered checks for the immediately following step. 6. Show: `📋 {CeremonyName} completed — facilitated by {Lead}. Decisions: {count} | Action items: {count}.` diff --git a/packages/squad-sdk/src/client/adapters/coordinator.ts b/packages/squad-sdk/src/client/adapters/coordinator.ts index c859a89ed..627a1e66a 100644 --- a/packages/squad-sdk/src/client/adapters/coordinator.ts +++ b/packages/squad-sdk/src/client/adapters/coordinator.ts @@ -128,7 +128,7 @@ You are the Squad coordinator. You route work to a team of specialists and keep ## Behavioral contract (same as Copilot) 10. **Response Mode Selection.** Pick the lightest mode that is correct, biasing upward when unsure: **Direct** (you answer from known facts, no spawn: status, roster, "who owns X", trivial questions); **Lightweight** (one specialist, minimal context: typo, small read-only lookup); **Standard** (one or more specialists with full charter/decision context: normal feature/bug work); **Full** (multi-agent fan-out plus reviewer gate and Scribe: cross-cutting or risky work). Acknowledge immediately before spawning: one line naming who you are launching and why, then spawn. -11. **Scribe spawn protocol and drop-box pattern.** Agents never write \`${S}/decisions.md\` directly: decisions go to \`${S}/decisions/inbox/\` (via \`squad_decide\`). After a substantive batch of work (or when the inbox is non-empty at session end), spawn **Scribe** (background/last) with its charter to: run \`squad_state_health\`; list the inbox; merge each entry into \`decisions.md\` (demote headings beneath a dated \`###\` entry, de-duplicate), re-read to verify, then delete only processed inbox entries; append a session log to \`${S}/log/\` and an entry to \`${S}/orchestration-log/\`; archive old decisions only through the state tools/\`squad nap\`, never by hand-deleting history. Scribe never commits mutable state. If a required state tool is unavailable, report it; do not fall back to unsafe direct writes. +11. **Scribe spawn protocol and drop-box pattern.** Agents never write \`${S}/decisions.md\` directly: decisions go to \`${S}/decisions/inbox/\` (via \`squad_decide\`). Spawn **Scribe** (background/last) only when the inbox holds accepted durable decisions to merge, with its charter (\`${S}/agents/scribe/charter.md\`, the only definition of its duties) inlined, to: run \`squad_state_health\`; list the inbox; merge each accepted entry into \`decisions.md\` (demote headings beneath a dated \`###\` entry, de-duplicate), re-read to verify, then delete only processed inbox entries. Scribe merges decisions only: it never writes session or orchestration logs or other agents' \`history.md\`, and never archives (size hygiene is the \`squad nap\` CLI). Scribe never commits mutable state. If a required state tool is unavailable, report it; do not fall back to unsafe direct writes. 12. **Reviewer rejection protocol and strict lockout.** Work that needs review goes to a reviewer (Lead, Tester or Rai as appropriate) before it is declared done. A reviewer returns APPROVE or REJECT with reasons. On REJECT the original author is **locked out** from revising that artifact: reassign the revision to a different member (or escalate to the Lead/architect); a locked-out author may not self-revise or re-submit. Re-review is required after the revision. If reviewers and authors deadlock, escalate to the user with both positions. Record verdicts via \`squad_decide\`. 13. **Rai (RAI Reviewer).** Rai performs Responsible-AI review: targeted ("RAI check", "is this safe to ship?"), pre-ship for user-facing artifacts, and pre-merge. Verdicts: 🟢 Green (proceed), 🟡 Yellow (advisory, proceed with recommendations attached), 🔴 Red (blocks shipping: triggers the reviewer rejection protocol with Rai naming a fix agent and re-reviewing). Rai runs in the background by default (non-blocking) and becomes a blocking gate only on Red; findings state WHAT is wrong, WHY it matters and HOW to fix it. Policy and audit trail: \`${S}/rai/policy.md\`, \`${S}/rai/audit-trail.md\` (append via state tools). 14. **Fact Checker (verification and devil's advocate).** Spawn the Fact Checker to verify claims, URLs, packages, APIs and external references, rating each ✅ verified, ⚠️ partially verified / caveat, ❌ contradicted, 🔍 unverifiable/needs a source; findings are advisory and never implement or decide. On request ("challenge this plan", "devil's advocate") it steelmans the plan, lists assumptions, runs a pre-mortem, proposes alternatives and states the risk being accepted. Audit trail: \`${S}/fact-checker/audit-trail.md\`. diff --git a/packages/squad-sdk/templates/README.md b/packages/squad-sdk/templates/README.md index fc2dce679..b0ad2a3fe 100644 --- a/packages/squad-sdk/templates/README.md +++ b/packages/squad-sdk/templates/README.md @@ -29,7 +29,7 @@ of these — they are NOT loaded on every turn. | `mcp-config.md` | Coordinator | MCP server integration details | | `model-selection-reference.md` | Coordinator | Per-agent model and reasoning-effort selection | | `multi-agent-format.md` | Coordinator | Assembling multi-agent artifact output | -| `orchestration-log.md` | Scribe | Writing per-agent orchestration log entries | +| `orchestration-log.md` | Legacy (no default writer; not Scribe) | Format of per-agent orchestration log entries | | `plugin-marketplace.md` | Coordinator | Plugin marketplace discovery and install flow | | `prd-intake.md` | Coordinator | PRD Mode — ingesting a spec for decomposition | | `ralph-reference.md` | Coordinator | Ralph work-monitor lifecycle and board format | diff --git a/packages/squad-sdk/templates/after-agent-reference.md b/packages/squad-sdk/templates/after-agent-reference.md index 401eaae75..839a6587e 100644 --- a/packages/squad-sdk/templates/after-agent-reference.md +++ b/packages/squad-sdk/templates/after-agent-reference.md @@ -7,9 +7,9 @@ (2) "Server Error Retry Loop" — context overflow after fan-out. Mitigated by lean post-work turn + Scribe delegation + compact result presentation. --> -**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe. That's ALL. No orchestration logs, no decision consolidation, no heavy file I/O. +**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe only when accepted durable decisions need merging. That's ALL. No session or orchestration logs, no decision consolidation, no heavy file I/O. -**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Full details go in orchestration log via Scribe. +**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Do not paste full agent output. Durable outcomes belong in decisions (`squad_decide`); each agent appends its own learnings to its own `history.md`. After each batch of agent work: @@ -22,63 +22,34 @@ After each batch of agent work: 3. **Show compact results:** `{emoji} {Name} — {1-line summary of what they did}` -4. **Spawn Scribe** (background, never wait). Only if agents ran or inbox has files: +4. **Spawn Scribe** (background, never wait) only when `decisions/inbox` holds accepted durable decisions to merge. Scribe's duties come only from its charter (`.squad/agents/scribe/charter.md`). The prompt below must stay identical to the **Scribe Spawn Template** in `squad.agent.md`: ``` agent_type: "general-purpose" model: "claude-haiku-4.5" mode: "background" name: "scribe" -description: "📋 Scribe: Log session & merge decisions" +description: "📋 Scribe: Merge durable decisions" prompt: | You are the Scribe. Read .squad/agents/scribe/charter.md. TEAM ROOT: {team_root} CURRENT_DATETIME: STATE_BACKEND: {state_backend} - SPAWN MANIFEST: {spawn_manifest} - Tasks (in order): - 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, - stop without mutating files or git state. - 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. - Record measurements. - 1. DECISIONS ARCHIVE [HARD GATE]: If decisions.md >= 20480 bytes, archive entries older than 30 days NOW. If >= 51200 bytes, archive entries older than 7 days. Do not skip this step. Follow the ARCHIVAL SAFETY RULES below — they are not optional. - 2. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, - merge entries into `decisions.md` with `squad_state_write`, delete processed inbox - entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body - beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at - `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. - 3. ORCHESTRATION LOG: Write `orchestration-log/{timestamp}-{agent}.md` with `squad_state_write` per agent. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms (e.g. `2026-06-02T21-15-30Z`). - 4. SESSION LOG: Write `log/{timestamp}-{topic}.md` with `squad_state_write`. Brief. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms. - 5. CROSS-AGENT: Append team updates to affected agents' `agents/{agent}/history.md` with `squad_state_append`. - 6. HISTORY SUMMARIZATION [HARD GATE]: If any history.md >= 15360 bytes (15KB), summarize now. The ARCHIVAL SAFETY RULES apply here too — summarization moves content out of a file exactly like decision archival does. - 7. HEALTH REPORT: Report ENTRY COUNTS, never file sizes: `N removed from source / N added to destination` for every archival, plus inbox count processed and history files summarized. Write with `squad_state_write` or `squad_state_append`. - - ARCHIVAL SAFETY RULES (apply to every operation that moves content out of a file): - A. DESTINATION MUST BE TRACKED. Before writing, run `git ls-files --error-unmatch `. - Exit 0 -> proceed. Non-zero -> redirect to an existing tracked archive file, or ABORT with a - clear error. `.squad/` is git-excluded in many checkouts: already-tracked files still commit, - but NEW files silently never do. Moving content into an untracked destination is a DELETION, - not an archive. Never create a new timestamped archive file and assume it will commit. - B. APPEND FIRST, VERIFY, THEN DELETE. Append to the destination. Re-read the destination and - confirm every moved heading is literally present AND the entry count grew by exactly the - number moved. Only then remove from the source. If the append cannot be verified, DO NOT - trim — leave the source intact and report the failure. Losing history is far worse than - leaving a file over its size gate. - C. COUNT ENTRIES, NOT BYTES. File size is not a valid integrity signal: a merge and an archive - in the same pass move size in opposite directions, so a size delta proves nothing. - D. NEVER REPORT A GATE OUTCOME YOU DID NOT MEASURE. "No archival required" must come from an - actual measurement. A gate that reports without measuring is worse than no gate. - E. If a state tool cannot perform these checks, STOP and report rather than proceeding with an - unverified move. - - Runtime state tools own persistence. Never switch branches, push note refs, reset - `.squad/`, or commit mutable squad state from this prompt. - - Never speak to user. ⚠️ End with plain text summary after all tool calls. + 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, stop without mutating files or git state. + 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. Record measurements. + 1. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, merge accepted durable decisions into `decisions.md` with `squad_state_write`, delete processed inbox entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. + 2. VERIFY: Re-read `decisions.md` and confirm every merged entry is present before deleting its inbox source. + 3. GIT COMMIT: Do not commit mutable squad state. If non-state repo files changed, report them for coordinator handling. + + Runtime state tools own persistence. Never switch branches, push note refs, reset `.squad/`, or commit mutable squad state from this prompt. + + Never speak to user. End with plain text summary after all tool calls. ``` +Scribe does not write session logs, orchestration logs or other agents' `history.md`, and it does not archive. Size hygiene (archiving old decisions, compressing large histories, pruning old logs) is the `squad nap` CLI command, not a Scribe task. + 5. **Immediately assess:** Does anything trigger follow-up work? Launch it NOW. 6. **Ralph check:** If Ralph is active (see Ralph — Work Monitor), after chaining any follow-up work, IMMEDIATELY run Ralph's work-check cycle (Step 1). Do NOT stop. Do NOT wait for user input. Ralph keeps the pipeline moving until the board is clear. diff --git a/packages/squad-sdk/templates/ceremony-reference.md b/packages/squad-sdk/templates/ceremony-reference.md index 78995215a..316c3c0ec 100644 --- a/packages/squad-sdk/templates/ceremony-reference.md +++ b/packages/squad-sdk/templates/ceremony-reference.md @@ -56,6 +56,7 @@ RULES: - Follow the agenda in order. - For each agenda item, spawn relevant participants as sub-tasks to gather their input. - Synthesize participant input into clear decisions and action items. +- Record each decision with `squad_decide` (one call per decision) so Scribe can merge it. - Keep to the time budget: {focused|extended}. - Output a structured summary at the end. @@ -73,7 +74,7 @@ TASK CONTEXT: - `all-relevant` → agents routed to the current task - `all-involved` → agents that participated in the completed batch - Named agents → spawn only those specific agents -6. **Scribe integration:** Spawn Scribe (background) at ceremony start to record decisions and action items. +6. **Scribe integration:** The facilitator records ceremony decisions with `squad_decide`. Scribe merges them afterwards like any other inbox entry; do not spawn Scribe at ceremony start. 7. **Output format:** ``` 📋 {CeremonyName} completed — facilitated by {Facilitator}. diff --git a/packages/squad-sdk/templates/model-selection-reference.md b/packages/squad-sdk/templates/model-selection-reference.md index eb8ec3a35..c0dd2e70c 100644 --- a/packages/squad-sdk/templates/model-selection-reference.md +++ b/packages/squad-sdk/templates/model-selection-reference.md @@ -70,7 +70,7 @@ Quality-sensitive work that is not code (architecture, research, verification, r | Copilot SDK Expert | Standard | Technical analysis that often touches code | Deep research → premium | | Designer / Visual | Premium | Vision-capable model required | — (never downgrade — vision is non-negotiable) | | DevRel / Writer | Standard | Language-heavy work benefits from a stronger model | Economy profile → fast | -| Scribe / Logger | Fast | Mechanical file ops | — (never bump Scribe) | +| Scribe | Fast | Mechanical decision merging | — (never bump Scribe) | | Git / Release | Fast | Mechanical ops — changelogs, tags, version bumps | — (never bump mechanical ops) | **Task complexity adjustments** (apply at most ONE — no cascading): @@ -119,7 +119,7 @@ Every spawn acknowledgment names the resolved model, its source and a short rati 🔧 Runtime Engineer ({model} · session) — refactoring auth module — session model inherited by this spawn 🎨 Experience Engineer ({model} · task-auto) — designing color system — visual task needs vision → premium tier -📋 Scribe ({model} · task-auto) — logging session — mechanical task → fast tier +📋 Scribe ({model} · task-auto) — merging decisions — mechanical task → fast tier ⚡ Lead ({model} · config) — reviewing proposal — agentModelOverrides.lead in .squad/config.json 📝 Docs Engineer ({model} · fallback) — updating docs — charter model unavailable; next in fast chain ``` diff --git a/packages/squad-sdk/templates/routing.md b/packages/squad-sdk/templates/routing.md index 1f49325cd..21de7c440 100644 --- a/packages/squad-sdk/templates/routing.md +++ b/packages/squad-sdk/templates/routing.md @@ -27,7 +27,7 @@ here only when their agent names also exist in the casting registry. ## Rules 1. **Eager by default** — spawn all agents who could usefully start work, including anticipatory downstream work. -2. **Scribe always runs** after substantial work, always as `mode: "background"`. Never blocks. +2. **Scribe runs only when accepted durable decisions need merging**, always as `mode: "background"`. Never blocks. 3. **Quick facts → coordinator answers directly.** Don't spawn an agent for "what port does the server run on?" 4. **When two agents could handle it**, pick the one whose domain is the primary concern. 5. **"Team, ..." → fan-out.** Spawn all relevant agents in parallel as `mode: "background"`. diff --git a/packages/squad-sdk/templates/scribe-charter.md b/packages/squad-sdk/templates/scribe-charter.md index 2f3c7fce6..6f303ee99 100644 --- a/packages/squad-sdk/templates/scribe-charter.md +++ b/packages/squad-sdk/templates/scribe-charter.md @@ -23,7 +23,7 @@ records, communications records, hooks, E2E records, or onboarding output. **State backend awareness:** Use runtime state tools for non-local backends, including `squad_state_read`, `squad_state_write`, `squad_state_append`, `squad_state_create_if_absent`, `squad_state_delete`, `squad_state_list`, `squad_state_health`, and `squad_decide`. Never switch state branches, push note refs, reset `.squad/`, or commit mutable state manually. If required state tools are unavailable, stop without mutating state and report the failure to the coordinator. -**Exclusive canonical artifacts:** When exactly one canonical artifact must exist — a retrospective, a session log, a claim marker — create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: +**Exclusive canonical artifacts:** When exactly one canonical artifact must exist, such as a claim marker, create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: - `error: "conflict"` — another Scribe already created the canonical artifact. Do **not** retry as a create and do **not** overwrite. Read the winner's content with `squad_state_read` and append to it if you have something to add. - `error: "uncertainty"` — the outcome is unknown. Do **not** assume success and do **not** write over the key. Stop and report the uncertainty in your final summary. diff --git a/packages/squad-sdk/templates/skills/agent-collaboration/SKILL.md b/packages/squad-sdk/templates/skills/agent-collaboration/SKILL.md index 054463cf8..8c7fb0695 100644 --- a/packages/squad-sdk/templates/skills/agent-collaboration/SKILL.md +++ b/packages/squad-sdk/templates/skills/agent-collaboration/SKILL.md @@ -38,5 +38,5 @@ If you have reviewer authority and reject work: the original author is locked ou ## Anti-Patterns - Don't read all agent charters — you only need your own context + decisions.md - Don't write directly to `.squad/decisions.md` — always use the inbox drop-box -- Don't modify other agents' history.md files — that's Scribe's job +- Don't modify other agents' history.md files — record team-relevant decisions with `squad_decide` instead - Don't assume CWD is the repo root — always use TEAM ROOT diff --git a/packages/squad-sdk/templates/skills/coordinator-init-mode/SKILL.md b/packages/squad-sdk/templates/skills/coordinator-init-mode/SKILL.md index 46585cd42..5351d92f4 100644 --- a/packages/squad-sdk/templates/skills/coordinator-init-mode/SKILL.md +++ b/packages/squad-sdk/templates/skills/coordinator-init-mode/SKILL.md @@ -33,7 +33,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user ⚛️ {CastName2} — Frontend Dev React, UI, components 🔧 {CastName3} — Backend Dev APIs, database, services 🧪 {CastName4} — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive 🛡️ Rai — (background) RAI awareness, content safety 🔍 Fact Checker — (verifier) Verification + Devil's Advocate @@ -73,7 +73,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md b/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md index b6948cb9b..468cb3262 100644 --- a/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md +++ b/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md @@ -26,10 +26,10 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/casting/registry.json` | **Authoritative name registry.** Persistent agent-to-name mappings. | Squad (Coordinator) | Squad (Coordinator) | | `.squad/casting/history.json` | **Derived / append-only.** Universe usage history and assignment snapshots. | Squad (Coordinator) — append only | Squad (Coordinator) | | `.squad/agents/{name}/charter.md` | **Authoritative agent identity.** Per-agent role and boundaries. | Squad (Coordinator) at creation; agent may not self-modify | Squad (Coordinator) reads to inline at spawn; owning agent receives via prompt | -| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only), Scribe (cross-agent updates, summarization) | Owning agent only | -| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | Scribe | Owning agent (read-only) | -| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Scribe | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Scribe | All agents (read-only) | +| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | +| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | +| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/packages/squad-sdk/templates/skills/init-mode/SKILL.md b/packages/squad-sdk/templates/skills/init-mode/SKILL.md index 5f99e7dab..6623165c9 100644 --- a/packages/squad-sdk/templates/skills/init-mode/SKILL.md +++ b/packages/squad-sdk/templates/skills/init-mode/SKILL.md @@ -36,7 +36,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user ⚛️ Frontend — Frontend Dev React, UI, components 🔧 Backend — Backend Dev APIs, database, services 🧪 Tester — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive ``` @@ -56,7 +56,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/packages/squad-sdk/templates/skills/retro-enforcement/SKILL.md b/packages/squad-sdk/templates/skills/retro-enforcement/SKILL.md index e7d319276..fdf0851cd 100644 --- a/packages/squad-sdk/templates/skills/retro-enforcement/SKILL.md +++ b/packages/squad-sdk/templates/skills/retro-enforcement/SKILL.md @@ -62,7 +62,7 @@ $workQueue = Get-PendingIssues | Sort-Object -Property Priority When `Test-RetroOverdue` returns `$true`: 1. **Do not start any other work** until the retro completes -2. **Spawn the facilitator agent** (Scribe or designated) with retro mode +2. **Spawn the facilitator agent** (the Lead or a designated member, never Scribe) with retro mode 3. **Wait for the log file** to be written to `.squad/log/` 4. **Verify action items** were created as GitHub Issues (not markdown) 5. **Resume normal round** after retro log confirmed diff --git a/packages/squad-sdk/templates/spawn-reference.md b/packages/squad-sdk/templates/spawn-reference.md index ec20f7f82..91d628fb3 100644 --- a/packages/squad-sdk/templates/spawn-reference.md +++ b/packages/squad-sdk/templates/spawn-reference.md @@ -159,7 +159,7 @@ prompt: | AFTER work (BEST-EFFORT — do NOT retry on failure): ⚠️ POST-WORK BUDGET: Spend at most 20 tool calls on post-work steps below. If you are running low on context or have used 60+ tool calls on primary work, - skip post-work entirely -- Scribe handles it independently. + skip post-work entirely and say so in your final summary. 1. APPEND learnings with `squad_state_append` to `agents/{name}/history.md`. Include architecture decisions, patterns, user preferences, and key file paths. Use `` as the entry timestamp. @@ -168,11 +168,11 @@ prompt: | unavailable, use `squad_state_write` to `decisions/inbox/{name}-{brief-slug}.md`. 3. If state tools are unavailable, skip post-work state persistence and report the backend/tool availability problem in your final summary. - 4. SKILL EXTRACTION is handled by Scribe — do NOT attempt it yourself. + 4. Do not write skills during post-work. Mention any reusable pattern in your final summary. ⚠️ STOP ON FAILURE: If ANY post-work step fails (git conflict, file not found, - permission error), SKIP it and move on. Do NOT retry. Scribe handles cleanup - independently. Your primary deliverable is already done — post-work is optional. + permission error), SKIP it and move on. Do NOT retry. Report what you skipped in + your final summary. Your primary deliverable is already done — post-work is optional. ⚠️ RESPONSE ORDER: After ALL tool calls, write a 2-3 sentence plain text summary as your FINAL output. No tool calls after this summary. diff --git a/packages/squad-sdk/templates/squad.agent.md.template b/packages/squad-sdk/templates/squad.agent.md.template index 32eab19d8..39c510ac8 100644 --- a/packages/squad-sdk/templates/squad.agent.md.template +++ b/packages/squad-sdk/templates/squad.agent.md.template @@ -125,7 +125,7 @@ requirements remain in `.github/PR_REQUIREMENTS.md`. **If you wrote code, generated artifacts, or produced domain work without dispatching to an agent, you violated this rule. The coordinator ROUTES — it does not BUILD. No exceptions.** -**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. +**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. **Resolve state backend:** Read `.squad/config.json` (at the resolved TEAM_ROOT) and check the `stateBackend` field. Valid values: `"local"` (default), `"orphan"`, `"two-layer"`. Legacy alias: `"worktree"` maps to `"local"`. Deprecated: `"git-notes"` maps to `"two-layer"` with a deprecation warning. Store as `STATE_BACKEND` and pass it into every spawn prompt. This determines how agents read and write mutable state (history, decisions, logs). Static config (charters, team.md, routing.md) always lives on disk regardless of backend. The `"two-layer"` option combines git-notes (commit-scoped annotations) with orphan branch (permanent state) — see the blog post for the full architecture. @@ -201,7 +201,6 @@ For each squad member with assigned issues, note them in the session context. Wh ``` 🔧 Runtime Engineer — error handling in index.js 🧪 Quality Engineer — writing test cases - 📋 Scribe — logging session ``` The acknowledgment goes in the same response as the `task` tool calls — text first, then tool calls. Keep it to 1-2 sentences plus the table. Don't narrate the plan; just show who's working on what. @@ -237,7 +236,7 @@ When spawning agents, include the role emoji in the `description` parameter to m - `name: "lead"`, `description: "🏗️ Lead: Reviewing architecture proposal"` - `name: "runtime-engineer"`, `description: "🔧 Runtime Engineer: Refactoring auth module"` - `name: "quality-engineer"`, `description: "🧪 Quality Engineer: Writing test cases"` -- `name: "scribe"`, `description: "📋 Scribe: Log session & merge decisions"` +- `name: "scribe"`, `description: "📋 Scribe: Merge durable decisions"` The `name` parameter generates the human-readable agent ID shown in the tasks panel — it MUST be the agent's lowercase cast name (e.g., `"runtime-engineer"`, `"quality-engineer"`). Without it, the platform shows generic slugs like "general-purpose-task" instead of the cast name. The emoji in `description` makes task spawn notifications visually consistent with the launch table shown to users. @@ -634,7 +633,7 @@ when needed, and present compact outcomes. Spawn Scribe only when durable decisi merging. Keep the same accountable owner for follow-up work unless a new independently deliverable outcome requires rerouting. -**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules, Scribe spawn template, and follow-up sequence. +**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules and follow-up sequence. Its Scribe spawn prompt is identical to the Scribe Spawn Template above; Scribe's duties come only from its charter. ### Ceremonies @@ -646,7 +645,7 @@ Ceremonies are structured team meetings where agents align before or after work. 1. Before spawning a work batch, check `.squad/ceremonies.md` for auto-triggered `before` ceremonies matching the current task condition. 2. After a batch completes, check for `after` ceremonies. Manual ceremonies run only when the user asks. 3. Spawn the facilitator (sync) using the template in the reference file. Facilitator spawns participants as sub-tasks. -4. For `before`: include ceremony summary in work batch spawn prompts. Spawn Scribe (background) to record. +4. For `before`: include ceremony summary in work batch spawn prompts. The facilitator records ceremony decisions with `squad_decide`; Scribe merges them later like any other inbox entry. 5. **Ceremony cooldown:** Skip auto-triggered checks for the immediately following step. 6. Show: `📋 {CeremonyName} completed — facilitated by {Lead}. Decisions: {count} | Action items: {count}.` diff --git a/templates/README.md b/templates/README.md index fc2dce679..b0ad2a3fe 100644 --- a/templates/README.md +++ b/templates/README.md @@ -29,7 +29,7 @@ of these — they are NOT loaded on every turn. | `mcp-config.md` | Coordinator | MCP server integration details | | `model-selection-reference.md` | Coordinator | Per-agent model and reasoning-effort selection | | `multi-agent-format.md` | Coordinator | Assembling multi-agent artifact output | -| `orchestration-log.md` | Scribe | Writing per-agent orchestration log entries | +| `orchestration-log.md` | Legacy (no default writer; not Scribe) | Format of per-agent orchestration log entries | | `plugin-marketplace.md` | Coordinator | Plugin marketplace discovery and install flow | | `prd-intake.md` | Coordinator | PRD Mode — ingesting a spec for decomposition | | `ralph-reference.md` | Coordinator | Ralph work-monitor lifecycle and board format | diff --git a/templates/after-agent-reference.md b/templates/after-agent-reference.md index 401eaae75..839a6587e 100644 --- a/templates/after-agent-reference.md +++ b/templates/after-agent-reference.md @@ -7,9 +7,9 @@ (2) "Server Error Retry Loop" — context overflow after fan-out. Mitigated by lean post-work turn + Scribe delegation + compact result presentation. --> -**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe. That's ALL. No orchestration logs, no decision consolidation, no heavy file I/O. +**⚡ Keep the post-work turn LEAN.** Coordinator's job: (1) present compact results, (2) spawn Scribe only when accepted durable decisions need merging. That's ALL. No session or orchestration logs, no decision consolidation, no heavy file I/O. -**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Full details go in orchestration log via Scribe. +**⚡ Context budget rule:** After collecting results from 3+ agents, use compact format (agent + 1-line outcome). Do not paste full agent output. Durable outcomes belong in decisions (`squad_decide`); each agent appends its own learnings to its own `history.md`. After each batch of agent work: @@ -22,63 +22,34 @@ After each batch of agent work: 3. **Show compact results:** `{emoji} {Name} — {1-line summary of what they did}` -4. **Spawn Scribe** (background, never wait). Only if agents ran or inbox has files: +4. **Spawn Scribe** (background, never wait) only when `decisions/inbox` holds accepted durable decisions to merge. Scribe's duties come only from its charter (`.squad/agents/scribe/charter.md`). The prompt below must stay identical to the **Scribe Spawn Template** in `squad.agent.md`: ``` agent_type: "general-purpose" model: "claude-haiku-4.5" mode: "background" name: "scribe" -description: "📋 Scribe: Log session & merge decisions" +description: "📋 Scribe: Merge durable decisions" prompt: | You are the Scribe. Read .squad/agents/scribe/charter.md. TEAM ROOT: {team_root} CURRENT_DATETIME: STATE_BACKEND: {state_backend} - SPAWN MANIFEST: {spawn_manifest} - Tasks (in order): - 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, - stop without mutating files or git state. - 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. - Record measurements. - 1. DECISIONS ARCHIVE [HARD GATE]: If decisions.md >= 20480 bytes, archive entries older than 30 days NOW. If >= 51200 bytes, archive entries older than 7 days. Do not skip this step. Follow the ARCHIVAL SAFETY RULES below — they are not optional. - 2. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, - merge entries into `decisions.md` with `squad_state_write`, delete processed inbox - entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body - beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at - `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. - 3. ORCHESTRATION LOG: Write `orchestration-log/{timestamp}-{agent}.md` with `squad_state_write` per agent. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms (e.g. `2026-06-02T21-15-30Z`). - 4. SESSION LOG: Write `log/{timestamp}-{topic}.md` with `squad_state_write`. Brief. Use ISO 8601 UTC timestamp. Replace `:` with `-` in `{timestamp}` so filenames are valid on all platforms. - 5. CROSS-AGENT: Append team updates to affected agents' `agents/{agent}/history.md` with `squad_state_append`. - 6. HISTORY SUMMARIZATION [HARD GATE]: If any history.md >= 15360 bytes (15KB), summarize now. The ARCHIVAL SAFETY RULES apply here too — summarization moves content out of a file exactly like decision archival does. - 7. HEALTH REPORT: Report ENTRY COUNTS, never file sizes: `N removed from source / N added to destination` for every archival, plus inbox count processed and history files summarized. Write with `squad_state_write` or `squad_state_append`. - - ARCHIVAL SAFETY RULES (apply to every operation that moves content out of a file): - A. DESTINATION MUST BE TRACKED. Before writing, run `git ls-files --error-unmatch `. - Exit 0 -> proceed. Non-zero -> redirect to an existing tracked archive file, or ABORT with a - clear error. `.squad/` is git-excluded in many checkouts: already-tracked files still commit, - but NEW files silently never do. Moving content into an untracked destination is a DELETION, - not an archive. Never create a new timestamped archive file and assume it will commit. - B. APPEND FIRST, VERIFY, THEN DELETE. Append to the destination. Re-read the destination and - confirm every moved heading is literally present AND the entry count grew by exactly the - number moved. Only then remove from the source. If the append cannot be verified, DO NOT - trim — leave the source intact and report the failure. Losing history is far worse than - leaving a file over its size gate. - C. COUNT ENTRIES, NOT BYTES. File size is not a valid integrity signal: a merge and an archive - in the same pass move size in opposite directions, so a size delta proves nothing. - D. NEVER REPORT A GATE OUTCOME YOU DID NOT MEASURE. "No archival required" must come from an - actual measurement. A gate that reports without measuring is worse than no gate. - E. If a state tool cannot perform these checks, STOP and report rather than proceeding with an - unverified move. - - Runtime state tools own persistence. Never switch branches, push note refs, reset - `.squad/`, or commit mutable squad state from this prompt. - - Never speak to user. ⚠️ End with plain text summary after all tool calls. + 0. PRE-CHECK: Run `squad_state_health` when available. If state tools are unavailable, stop without mutating files or git state. + 0b. PRE-CHECK: Read `decisions.md` and list `decisions/inbox` with state tools. Record measurements. + 1. DECISION INBOX: Use `squad_state_list` and `squad_state_read` on `decisions/inbox`, merge accepted durable decisions into `decisions.md` with `squad_state_write`, delete processed inbox entries with `squad_state_delete`, and deduplicate. Before splicing an inbox body beneath an `###` entry, DEMOTE its headings so its shallowest heading lands at `####` (`##` -> `####`). Preserve relative structure. Never emit an `##` under an `###`. + 2. VERIFY: Re-read `decisions.md` and confirm every merged entry is present before deleting its inbox source. + 3. GIT COMMIT: Do not commit mutable squad state. If non-state repo files changed, report them for coordinator handling. + + Runtime state tools own persistence. Never switch branches, push note refs, reset `.squad/`, or commit mutable squad state from this prompt. + + Never speak to user. End with plain text summary after all tool calls. ``` +Scribe does not write session logs, orchestration logs or other agents' `history.md`, and it does not archive. Size hygiene (archiving old decisions, compressing large histories, pruning old logs) is the `squad nap` CLI command, not a Scribe task. + 5. **Immediately assess:** Does anything trigger follow-up work? Launch it NOW. 6. **Ralph check:** If Ralph is active (see Ralph — Work Monitor), after chaining any follow-up work, IMMEDIATELY run Ralph's work-check cycle (Step 1). Do NOT stop. Do NOT wait for user input. Ralph keeps the pipeline moving until the board is clear. diff --git a/templates/ceremony-reference.md b/templates/ceremony-reference.md index 78995215a..316c3c0ec 100644 --- a/templates/ceremony-reference.md +++ b/templates/ceremony-reference.md @@ -56,6 +56,7 @@ RULES: - Follow the agenda in order. - For each agenda item, spawn relevant participants as sub-tasks to gather their input. - Synthesize participant input into clear decisions and action items. +- Record each decision with `squad_decide` (one call per decision) so Scribe can merge it. - Keep to the time budget: {focused|extended}. - Output a structured summary at the end. @@ -73,7 +74,7 @@ TASK CONTEXT: - `all-relevant` → agents routed to the current task - `all-involved` → agents that participated in the completed batch - Named agents → spawn only those specific agents -6. **Scribe integration:** Spawn Scribe (background) at ceremony start to record decisions and action items. +6. **Scribe integration:** The facilitator records ceremony decisions with `squad_decide`. Scribe merges them afterwards like any other inbox entry; do not spawn Scribe at ceremony start. 7. **Output format:** ``` 📋 {CeremonyName} completed — facilitated by {Facilitator}. diff --git a/templates/model-selection-reference.md b/templates/model-selection-reference.md index eb8ec3a35..c0dd2e70c 100644 --- a/templates/model-selection-reference.md +++ b/templates/model-selection-reference.md @@ -70,7 +70,7 @@ Quality-sensitive work that is not code (architecture, research, verification, r | Copilot SDK Expert | Standard | Technical analysis that often touches code | Deep research → premium | | Designer / Visual | Premium | Vision-capable model required | — (never downgrade — vision is non-negotiable) | | DevRel / Writer | Standard | Language-heavy work benefits from a stronger model | Economy profile → fast | -| Scribe / Logger | Fast | Mechanical file ops | — (never bump Scribe) | +| Scribe | Fast | Mechanical decision merging | — (never bump Scribe) | | Git / Release | Fast | Mechanical ops — changelogs, tags, version bumps | — (never bump mechanical ops) | **Task complexity adjustments** (apply at most ONE — no cascading): @@ -119,7 +119,7 @@ Every spawn acknowledgment names the resolved model, its source and a short rati 🔧 Runtime Engineer ({model} · session) — refactoring auth module — session model inherited by this spawn 🎨 Experience Engineer ({model} · task-auto) — designing color system — visual task needs vision → premium tier -📋 Scribe ({model} · task-auto) — logging session — mechanical task → fast tier +📋 Scribe ({model} · task-auto) — merging decisions — mechanical task → fast tier ⚡ Lead ({model} · config) — reviewing proposal — agentModelOverrides.lead in .squad/config.json 📝 Docs Engineer ({model} · fallback) — updating docs — charter model unavailable; next in fast chain ``` diff --git a/templates/routing.md b/templates/routing.md index 1f49325cd..21de7c440 100644 --- a/templates/routing.md +++ b/templates/routing.md @@ -27,7 +27,7 @@ here only when their agent names also exist in the casting registry. ## Rules 1. **Eager by default** — spawn all agents who could usefully start work, including anticipatory downstream work. -2. **Scribe always runs** after substantial work, always as `mode: "background"`. Never blocks. +2. **Scribe runs only when accepted durable decisions need merging**, always as `mode: "background"`. Never blocks. 3. **Quick facts → coordinator answers directly.** Don't spawn an agent for "what port does the server run on?" 4. **When two agents could handle it**, pick the one whose domain is the primary concern. 5. **"Team, ..." → fan-out.** Spawn all relevant agents in parallel as `mode: "background"`. diff --git a/templates/scribe-charter.md b/templates/scribe-charter.md index 2f3c7fce6..6f303ee99 100644 --- a/templates/scribe-charter.md +++ b/templates/scribe-charter.md @@ -23,7 +23,7 @@ records, communications records, hooks, E2E records, or onboarding output. **State backend awareness:** Use runtime state tools for non-local backends, including `squad_state_read`, `squad_state_write`, `squad_state_append`, `squad_state_create_if_absent`, `squad_state_delete`, `squad_state_list`, `squad_state_health`, and `squad_decide`. Never switch state branches, push note refs, reset `.squad/`, or commit mutable state manually. If required state tools are unavailable, stop without mutating state and report the failure to the coordinator. -**Exclusive canonical artifacts:** When exactly one canonical artifact must exist — a retrospective, a session log, a claim marker — create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: +**Exclusive canonical artifacts:** When exactly one canonical artifact must exist, such as a claim marker, create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: - `error: "conflict"` — another Scribe already created the canonical artifact. Do **not** retry as a create and do **not** overwrite. Read the winner's content with `squad_state_read` and append to it if you have something to add. - `error: "uncertainty"` — the outcome is unknown. Do **not** assume success and do **not** write over the key. Stop and report the uncertainty in your final summary. diff --git a/templates/skills/agent-collaboration/SKILL.md b/templates/skills/agent-collaboration/SKILL.md index 054463cf8..8c7fb0695 100644 --- a/templates/skills/agent-collaboration/SKILL.md +++ b/templates/skills/agent-collaboration/SKILL.md @@ -38,5 +38,5 @@ If you have reviewer authority and reject work: the original author is locked ou ## Anti-Patterns - Don't read all agent charters — you only need your own context + decisions.md - Don't write directly to `.squad/decisions.md` — always use the inbox drop-box -- Don't modify other agents' history.md files — that's Scribe's job +- Don't modify other agents' history.md files — record team-relevant decisions with `squad_decide` instead - Don't assume CWD is the repo root — always use TEAM ROOT diff --git a/templates/skills/coordinator-init-mode/SKILL.md b/templates/skills/coordinator-init-mode/SKILL.md index 46585cd42..5351d92f4 100644 --- a/templates/skills/coordinator-init-mode/SKILL.md +++ b/templates/skills/coordinator-init-mode/SKILL.md @@ -33,7 +33,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user ⚛️ {CastName2} — Frontend Dev React, UI, components 🔧 {CastName3} — Backend Dev APIs, database, services 🧪 {CastName4} — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive 🛡️ Rai — (background) RAI awareness, content safety 🔍 Fact Checker — (verifier) Verification + Devil's Advocate @@ -73,7 +73,7 @@ No team exists yet. **Propose one — but DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. Rai's charter is seeded from the `Rai-charter.md` template, and `.squad/rai/policy.md` is seeded from `rai-policy.md`. Fact Checker's charter is seeded from `fact-checker-charter.md` and `.squad/fact-checker/policy.md` is seeded from `fact-checker-policy.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/templates/skills/coordinator-source-of-truth/SKILL.md b/templates/skills/coordinator-source-of-truth/SKILL.md index b6948cb9b..468cb3262 100644 --- a/templates/skills/coordinator-source-of-truth/SKILL.md +++ b/templates/skills/coordinator-source-of-truth/SKILL.md @@ -26,10 +26,10 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/casting/registry.json` | **Authoritative name registry.** Persistent agent-to-name mappings. | Squad (Coordinator) | Squad (Coordinator) | | `.squad/casting/history.json` | **Derived / append-only.** Universe usage history and assignment snapshots. | Squad (Coordinator) — append only | Squad (Coordinator) | | `.squad/agents/{name}/charter.md` | **Authoritative agent identity.** Per-agent role and boundaries. | Squad (Coordinator) at creation; agent may not self-modify | Squad (Coordinator) reads to inline at spawn; owning agent receives via prompt | -| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only), Scribe (cross-agent updates, summarization) | Owning agent only | -| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | Scribe | Owning agent (read-only) | -| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Scribe | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Scribe | All agents (read-only) | +| `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | +| `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | +| `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/templates/skills/init-mode/SKILL.md b/templates/skills/init-mode/SKILL.md index 5f99e7dab..6623165c9 100644 --- a/templates/skills/init-mode/SKILL.md +++ b/templates/skills/init-mode/SKILL.md @@ -36,7 +36,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user ⚛️ Frontend — Frontend Dev React, UI, components 🔧 Backend — Backend Dev APIs, database, services 🧪 Tester — Tester Tests, quality, edge cases -📋 Scribe — (silent) Memory, decisions, session logs +📋 Scribe — (silent) Durable decision merging 🔄 Ralph — (monitor) Work queue, backlog, keep-alive ``` @@ -56,7 +56,7 @@ No team exists yet. Propose one — but **DO NOT create any files until the user **Casting state initialization:** Copy `.squad/templates/casting-policy.json` to `.squad/casting/policy.json` (or create from defaults). Create `registry.json` (entries: persistent_name, universe, created_at, legacy_named: false, status: "active") and `history.json` (first assignment snapshot with unique assignment_id). -**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter includes maintaining `decisions.md` and cross-agent context sharing. +**Seeding:** Each agent's `history.md` starts with the project description, tech stack, and the user's name so they have day-1 context. Agent folder names are the cast name in lowercase (e.g., `.squad/agents/ripley/`). The Scribe's charter covers only merging accepted durable decisions into `decisions.md`. **Team.md structure:** `team.md` MUST contain a section titled exactly `## Members` (not "## Team Roster" or other variations) containing the roster table. This header is hard-coded in GitHub workflows (`squad-heartbeat.yml`, `squad-issue-assign.yml`, `squad-triage.yml`, `sync-squad-labels.yml`) for label automation. If the header is missing or titled differently, label routing breaks. diff --git a/templates/skills/retro-enforcement/SKILL.md b/templates/skills/retro-enforcement/SKILL.md index e7d319276..fdf0851cd 100644 --- a/templates/skills/retro-enforcement/SKILL.md +++ b/templates/skills/retro-enforcement/SKILL.md @@ -62,7 +62,7 @@ $workQueue = Get-PendingIssues | Sort-Object -Property Priority When `Test-RetroOverdue` returns `$true`: 1. **Do not start any other work** until the retro completes -2. **Spawn the facilitator agent** (Scribe or designated) with retro mode +2. **Spawn the facilitator agent** (the Lead or a designated member, never Scribe) with retro mode 3. **Wait for the log file** to be written to `.squad/log/` 4. **Verify action items** were created as GitHub Issues (not markdown) 5. **Resume normal round** after retro log confirmed diff --git a/templates/spawn-reference.md b/templates/spawn-reference.md index ec20f7f82..91d628fb3 100644 --- a/templates/spawn-reference.md +++ b/templates/spawn-reference.md @@ -159,7 +159,7 @@ prompt: | AFTER work (BEST-EFFORT — do NOT retry on failure): ⚠️ POST-WORK BUDGET: Spend at most 20 tool calls on post-work steps below. If you are running low on context or have used 60+ tool calls on primary work, - skip post-work entirely -- Scribe handles it independently. + skip post-work entirely and say so in your final summary. 1. APPEND learnings with `squad_state_append` to `agents/{name}/history.md`. Include architecture decisions, patterns, user preferences, and key file paths. Use `` as the entry timestamp. @@ -168,11 +168,11 @@ prompt: | unavailable, use `squad_state_write` to `decisions/inbox/{name}-{brief-slug}.md`. 3. If state tools are unavailable, skip post-work state persistence and report the backend/tool availability problem in your final summary. - 4. SKILL EXTRACTION is handled by Scribe — do NOT attempt it yourself. + 4. Do not write skills during post-work. Mention any reusable pattern in your final summary. ⚠️ STOP ON FAILURE: If ANY post-work step fails (git conflict, file not found, - permission error), SKIP it and move on. Do NOT retry. Scribe handles cleanup - independently. Your primary deliverable is already done — post-work is optional. + permission error), SKIP it and move on. Do NOT retry. Report what you skipped in + your final summary. Your primary deliverable is already done — post-work is optional. ⚠️ RESPONSE ORDER: After ALL tool calls, write a 2-3 sentence plain text summary as your FINAL output. No tool calls after this summary. diff --git a/templates/squad.agent.md.template b/templates/squad.agent.md.template index 32eab19d8..39c510ac8 100644 --- a/templates/squad.agent.md.template +++ b/templates/squad.agent.md.template @@ -125,7 +125,7 @@ requirements remain in `.github/PR_REQUIREMENTS.md`. **If you wrote code, generated artifacts, or produced domain work without dispatching to an agent, you violated this rule. The coordinator ROUTES — it does not BUILD. No exceptions.** -**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt and Scribe log so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. +**On every session start:** Run `git config user.name` to identify the current user, and **resolve the team root** (see Worktree Awareness). Store the team root — all `.squad/` paths must be resolved relative to it. Resolve `CURRENT_DATETIME` once from the `` value in your system context. Sanity-check that it is a real ISO-like timestamp, not placeholder text, with a plausible year and timezone (`Z` or an offset). If the system value is missing or implausible, run a local date command and use that result instead (`date +"%Y-%m-%dT%H:%M:%S%z"` on macOS/Linux, or `Get-Date -Format o` in PowerShell). Pass the team root and the resolved literal current datetime into every spawn prompt as `TEAM_ROOT` and `CURRENT_DATETIME` respectively. Never pass placeholder text for `CURRENT_DATETIME`. Pass the current user's name into every agent spawn prompt so the team always knows who requested the work. Check `.squad/identity/now.md` if it exists — it tells you what the team was last focused on. Update it if the focus has shifted. **Resolve state backend:** Read `.squad/config.json` (at the resolved TEAM_ROOT) and check the `stateBackend` field. Valid values: `"local"` (default), `"orphan"`, `"two-layer"`. Legacy alias: `"worktree"` maps to `"local"`. Deprecated: `"git-notes"` maps to `"two-layer"` with a deprecation warning. Store as `STATE_BACKEND` and pass it into every spawn prompt. This determines how agents read and write mutable state (history, decisions, logs). Static config (charters, team.md, routing.md) always lives on disk regardless of backend. The `"two-layer"` option combines git-notes (commit-scoped annotations) with orphan branch (permanent state) — see the blog post for the full architecture. @@ -201,7 +201,6 @@ For each squad member with assigned issues, note them in the session context. Wh ``` 🔧 Runtime Engineer — error handling in index.js 🧪 Quality Engineer — writing test cases - 📋 Scribe — logging session ``` The acknowledgment goes in the same response as the `task` tool calls — text first, then tool calls. Keep it to 1-2 sentences plus the table. Don't narrate the plan; just show who's working on what. @@ -237,7 +236,7 @@ When spawning agents, include the role emoji in the `description` parameter to m - `name: "lead"`, `description: "🏗️ Lead: Reviewing architecture proposal"` - `name: "runtime-engineer"`, `description: "🔧 Runtime Engineer: Refactoring auth module"` - `name: "quality-engineer"`, `description: "🧪 Quality Engineer: Writing test cases"` -- `name: "scribe"`, `description: "📋 Scribe: Log session & merge decisions"` +- `name: "scribe"`, `description: "📋 Scribe: Merge durable decisions"` The `name` parameter generates the human-readable agent ID shown in the tasks panel — it MUST be the agent's lowercase cast name (e.g., `"runtime-engineer"`, `"quality-engineer"`). Without it, the platform shows generic slugs like "general-purpose-task" instead of the cast name. The emoji in `description` makes task spawn notifications visually consistent with the launch table shown to users. @@ -634,7 +633,7 @@ when needed, and present compact outcomes. Spawn Scribe only when durable decisi merging. Keep the same accountable owner for follow-up work unless a new independently deliverable outcome requires rerouting. -**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules, Scribe spawn template, and follow-up sequence. +**On-demand reference:** Read `.squad/templates/after-agent-reference.md` for the full silent-success rules and follow-up sequence. Its Scribe spawn prompt is identical to the Scribe Spawn Template above; Scribe's duties come only from its charter. ### Ceremonies @@ -646,7 +645,7 @@ Ceremonies are structured team meetings where agents align before or after work. 1. Before spawning a work batch, check `.squad/ceremonies.md` for auto-triggered `before` ceremonies matching the current task condition. 2. After a batch completes, check for `after` ceremonies. Manual ceremonies run only when the user asks. 3. Spawn the facilitator (sync) using the template in the reference file. Facilitator spawns participants as sub-tasks. -4. For `before`: include ceremony summary in work batch spawn prompts. Spawn Scribe (background) to record. +4. For `before`: include ceremony summary in work batch spawn prompts. The facilitator records ceremony decisions with `squad_decide`; Scribe merges them later like any other inbox entry. 5. **Ceremony cooldown:** Skip auto-triggered checks for the immediately following step. 6. Show: `📋 {CeremonyName} completed — facilitated by {Lead}. Decisions: {count} | Action items: {count}.` diff --git a/test/ci/scribe-template.test.ts b/test/ci/scribe-template.test.ts index d09ad5b1e..0545d42d6 100644 --- a/test/ci/scribe-template.test.ts +++ b/test/ci/scribe-template.test.ts @@ -5,7 +5,7 @@ */ import { describe, it, expect } from 'vitest'; -import { readFileSync } from 'node:fs'; +import { readFileSync, readdirSync, statSync } from 'node:fs'; import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; @@ -45,4 +45,71 @@ describe('Scribe charter — bounded durable-decision contract', () => { expect(content).toContain('or decision-making.'); expect(content).toContain('**I am invisible.**'); }); + + it('names no session log or retrospective as an exclusive artifact', () => { + const paragraph = content.split(/\r?\n/).find(line => line.startsWith('**Exclusive canonical artifacts:**')) ?? ''; + expect(paragraph).toContain('squad_state_create_if_absent'); + expect(paragraph).not.toMatch(/session log|retrospective/i); + }); +}); + +describe('Scribe contract — every prompt surface agrees with the charter', () => { + const read = (relPath: string) => readFileSync(resolve(ROOT, relPath), 'utf-8').replace(/\r\n/g, '\n'); + const promptAfter = (text: string, marker: string) => { + const open = text.indexOf('```', text.indexOf(marker)); + const block = text.slice(open + 3, text.indexOf('```', open + 3)); + return block.slice(block.indexOf('prompt: |')); + }; + const inline = promptAfter(read('.squad-templates/squad.agent.md'), '**Scribe Spawn Template**'); + const afterAgent = promptAfter(read('.squad-templates/after-agent-reference.md'), '**Spawn Scribe**'); + + it('after-agent-reference.md repeats the coordinator inline Scribe prompt exactly', () => { + expect(afterAgent).toBe(inline); + }); + + it('no Scribe spawn prompt asks for logs, history writes or archival', () => { + for (const prompt of [inline, afterAgent]) { + expect(prompt).not.toMatch(/SESSION LOG|ORCHESTRATION LOG|CROSS-AGENT|HISTORY SUMMARIZATION|DECISIONS ARCHIVE/); + } + }); + + it('no template file assigns Scribe a retired duty', () => { + // Retired phrases from the pre-#2030 broad Scribe. Checked in every file under + // .squad-templates/ (mirrors are pinned to it by template-sync.test.ts). + const retired = [ + '**Scribe always runs**', + 'handled by Scribe', + 'Scribe handles', + 'Spawn Scribe (background) at ceremony start', + 'Spawn Scribe (background) to record', + 'Scribe (cross-agent updates', + 'Memory, decisions, session logs', + "that's Scribe's job", + 'Log session & merge decisions', + 'Scribe — logging session', + 'and Scribe log', + 'orchestration log via Scribe', + 'cross-agent context sharing', + 'Scribe / Logger', + 'Scribe or designated', + ]; + const files = (readdirSync(resolve(ROOT, '.squad-templates'), { recursive: true }) as string[]) + .map((f) => `.squad-templates/${f.replace(/\\/g, '/')}`) + .filter((f) => statSync(resolve(ROOT, f)).isFile()); + expect(files.length).toBeGreaterThan(50); + for (const file of files) { + const text = read(file); + for (const phrase of retired) expect(text, `${file}: ${phrase}`).not.toContain(phrase); + } + }); + + it('the gh-aw builtin charter matches the template charter', () => { + expect(read('workflows/shared/builtins/scribe-charter.md')).toBe(read('.squad-templates/scribe-charter.md')); + }); + + it('the watch decision-hygiene prompt defers to the charter and does not archive', () => { + const source = read('packages/squad-cli/src/cli/commands/watch/capabilities/decision-hygiene.ts'); + expect(source).toContain('Read .squad/agents/scribe/charter.md'); + expect(source).not.toContain('If you archive anything'); + }); }); diff --git a/test/clients.test.ts b/test/clients.test.ts index c173b626d..338daf70d 100644 --- a/test/clients.test.ts +++ b/test/clients.test.ts @@ -246,7 +246,7 @@ describe('coordinator Ralph mode', () => { describe('coordinator behavioral-contract parity', () => { const sections: Array<[string, RegExp[]]> = [ ['Response Mode', [/Response Mode Selection/, /\*\*Direct\*\*/, /\*\*Lightweight\*\*/, /\*\*Standard\*\*/, /\*\*Full\*\*/]], - ['Scribe', [/Scribe spawn protocol and drop-box/, /decisions\/inbox\//, /orchestration-log\//, /\/log\//, /squad_state_health/]], + ['Scribe', [/Scribe spawn protocol and drop-box/, /decisions\/inbox\//, /squad_state_health/, /Scribe merges decisions only/, /squad nap/]], ['Reviewer Rejection', [/Reviewer rejection protocol and strict lockout/, /locked out/, /may not self-revise/]], ['Rai', [/Rai \(RAI Reviewer\)/, /🟢 Green/, /🟡 Yellow/, /🔴 Red/, /blocks shipping/]], ['Fact Checker', [/Fact Checker \(verification and devil's advocate\)/, /✅/, /⚠️/, /❌/, /🔍/, /steelmans/, /pre-mortem/]], diff --git a/workflows/shared/builtins/scribe-charter.md b/workflows/shared/builtins/scribe-charter.md index 2f3c7fce6..6f303ee99 100644 --- a/workflows/shared/builtins/scribe-charter.md +++ b/workflows/shared/builtins/scribe-charter.md @@ -23,7 +23,7 @@ records, communications records, hooks, E2E records, or onboarding output. **State backend awareness:** Use runtime state tools for non-local backends, including `squad_state_read`, `squad_state_write`, `squad_state_append`, `squad_state_create_if_absent`, `squad_state_delete`, `squad_state_list`, `squad_state_health`, and `squad_decide`. Never switch state branches, push note refs, reset `.squad/`, or commit mutable state manually. If required state tools are unavailable, stop without mutating state and report the failure to the coordinator. -**Exclusive canonical artifacts:** When exactly one canonical artifact must exist — a retrospective, a session log, a claim marker — create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: +**Exclusive canonical artifacts:** When exactly one canonical artifact must exist, such as a claim marker, create it with `squad_state_create_if_absent`, never `squad_state_write`. It creates the key atomically only when absent, so exactly one Scribe wins and existing content is never overwritten. Handle its two failure shapes explicitly: - `error: "conflict"` — another Scribe already created the canonical artifact. Do **not** retry as a create and do **not** overwrite. Read the winner's content with `squad_state_read` and append to it if you have something to add. - `error: "uncertainty"` — the outcome is unknown. Do **not** assume success and do **not** write over the key. Stop and report the uncertainty in your final summary. diff --git a/workflows/squad-workflows.manifest.json b/workflows/squad-workflows.manifest.json index de3df5c09..df8483481 100644 --- a/workflows/squad-workflows.manifest.json +++ b/workflows/squad-workflows.manifest.json @@ -273,7 +273,7 @@ "package_destination": ".github/aw/squad/runtime/shared/builtins/scribe-charter.md", "destination": ".github/workflows/shared/builtins/scribe-charter.md", "ownership": "manifest", - "sha256": "01ab375efa4d03b48ddfc51b43374b24646b521c24ac1b881113789f89926044" + "sha256": "7e0669196708249629a7ffb5c92f3d2be0b8e8489489586aeae91e0af5b0a0ad" }, { "path": "shared/builtins/ralph-charter.md", From 80b694e3e9bae9f7ef53fd1866d97594abf95374 Mon Sep 17 00:00:00 2001 From: Jose Luis Latorre Millas Date: Tue, 10 Nov 2026 20:11:16 +0100 Subject: [PATCH 2/3] fix(templates): drop Scribe commit duties and let the retro facilitator write the retro log Follow-up from review: - secret-handling, worktree-reference, gh-auth-isolation and e2e-template-testing still had Scribe commit .squad/ changes, which its charter forbids. The pre-commit secret validation now applies to whoever commits .squad/ changes, and the worktree notes say the changes are committed with the work (runtime state tools persist mutable state on non-local backends). - retro-enforcement waits for the retro facilitator (never Scribe) to write .squad/log/, but the source-of-truth writer table did not allow it. The facilitator is now listed for retro logs. - the Scribe guard rejects the retired commit phrases and checks the facilitator can write the retro log. --- .changeset/scribe-single-definition.md | 2 +- .../coordinator-source-of-truth/SKILL.md | 2 +- .../skills/e2e-template-testing/SKILL.md | 2 +- .../skills/gh-auth-isolation/SKILL.md | 2 +- .../skills/secret-handling/SKILL.md | 16 +++++++++------- .squad-templates/worktree-reference.md | 4 ++-- .../coordinator-source-of-truth/SKILL.md | 2 +- .../skills/e2e-template-testing/SKILL.md | 2 +- .../skills/gh-auth-isolation/SKILL.md | 2 +- .../templates/skills/secret-handling/SKILL.md | 16 +++++++++------- .../squad-cli/templates/worktree-reference.md | 4 ++-- .../coordinator-source-of-truth/SKILL.md | 2 +- .../skills/e2e-template-testing/SKILL.md | 2 +- .../skills/gh-auth-isolation/SKILL.md | 2 +- .../templates/skills/secret-handling/SKILL.md | 16 +++++++++------- .../squad-sdk/templates/worktree-reference.md | 4 ++-- .../coordinator-source-of-truth/SKILL.md | 2 +- templates/skills/e2e-template-testing/SKILL.md | 2 +- templates/skills/gh-auth-isolation/SKILL.md | 2 +- templates/skills/secret-handling/SKILL.md | 16 +++++++++------- templates/worktree-reference.md | 4 ++-- test/ci/scribe-template.test.ts | 18 ++++++++++++++++++ 22 files changed, 75 insertions(+), 49 deletions(-) diff --git a/.changeset/scribe-single-definition.md b/.changeset/scribe-single-definition.md index ecd9f4875..156f3d0a6 100644 --- a/.changeset/scribe-single-definition.md +++ b/.changeset/scribe-single-definition.md @@ -3,4 +3,4 @@ "@bradygaster/squad-sdk": patch --- -Give Scribe one definition. Every prompt surface (coordinator after-agent reference, host coordinator digest, routing template, spawn reference, ceremony reference, model-selection reference, built-in skills, the templates README and the watch decision-hygiene prompt) now matches the bounded Scribe charter: Scribe merges accepted durable decisions only. Session logs, orchestration logs, cross-agent history appends and archival are no longer requested from Scribe; size hygiene is `squad nap`. The charter itself no longer lists a session log or a retrospective among the artifacts Scribe creates. +Give Scribe one definition. Every prompt surface (coordinator after-agent reference, host coordinator digest, routing template, spawn reference, ceremony reference, model-selection reference, built-in skills, the templates README and the watch decision-hygiene prompt) now matches the bounded Scribe charter: Scribe merges accepted durable decisions only. Session logs, orchestration logs, cross-agent history appends and archival are no longer requested from Scribe; size hygiene is `squad nap`. The charter itself no longer lists a session log or a retrospective among the artifacts Scribe creates. The secret-handling, worktree, gh-auth-isolation and e2e-testing references no longer have Scribe commit `.squad/` changes (pre-commit secret validation now applies to whoever commits them), and the source-of-truth table lets the retrospective facilitator write the retro log that the retro gate waits for. diff --git a/.squad-templates/skills/coordinator-source-of-truth/SKILL.md b/.squad-templates/skills/coordinator-source-of-truth/SKILL.md index 468cb3262..d88e02f72 100644 --- a/.squad-templates/skills/coordinator-source-of-truth/SKILL.md +++ b/.squad-templates/skills/coordinator-source-of-truth/SKILL.md @@ -29,7 +29,7 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | | `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | | `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime, `squad watch` capabilities, and the retrospective facilitator (retro logs only); not Scribe | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/.squad-templates/skills/e2e-template-testing/SKILL.md b/.squad-templates/skills/e2e-template-testing/SKILL.md index d1b38d94e..37ac64e47 100644 --- a/.squad-templates/skills/e2e-template-testing/SKILL.md +++ b/.squad-templates/skills/e2e-template-testing/SKILL.md @@ -429,7 +429,7 @@ needs every row — pick the scenarios relevant to your modification. |---|----------|----------------|----------| | 1 | Basic init + task | Templates applied, agent spawned, work produced | — | | 2 | Cross-branch persistence | State survives `git checkout` (if state-backend) | — | -| 3 | Scribe behavior | Scribe commits to correct target | — | +| 3 | Scribe behavior | Scribe merges the decisions inbox into `decisions.md` through the state tools and commits nothing | — | | 4 | PR cleanliness | Feature branch PR has no leaked state files | — | | 5 | Migration path | Existing squad picks up new template behavior | — | | 6 | Edge case: empty repo | Init works in repo with single commit | — | diff --git a/.squad-templates/skills/gh-auth-isolation/SKILL.md b/.squad-templates/skills/gh-auth-isolation/SKILL.md index 894955c1d..a3031c700 100644 --- a/.squad-templates/skills/gh-auth-isolation/SKILL.md +++ b/.squad-templates/skills/gh-auth-isolation/SKILL.md @@ -177,7 +177,7 @@ git push https://personaluser:$token@github.com/personaluser/repo.git main - ❌ **Hardcoding tokens** in scripts, environment variables, or committed files. Use `gh auth token --user` to extract at runtime. - ❌ **Assuming the default `gh` auth works** for all repos. EMU accounts can't access personal repos and vice versa. - ❌ **Switching `gh auth login`** globally mid-session. This changes the default for ALL processes and can break parallel agents. -- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed by Scribe. Use `gh`'s credential store. +- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed with the team state. Use `gh`'s credential store. - ❌ **Ignoring token cleanup** after inline HTTPS pushes. Always reset the remote URL to avoid persisting tokens. - ❌ **Using `gh auth switch`** in multi-agent sessions. One agent switching affects all others sharing the shell. - ❌ **Mixing EMU and personal operations** in the same git clone. Use separate clones or explicit remote URLs per operation. diff --git a/.squad-templates/skills/secret-handling/SKILL.md b/.squad-templates/skills/secret-handling/SKILL.md index b6c6b31b6..dd9727ebc 100644 --- a/.squad-templates/skills/secret-handling/SKILL.md +++ b/.squad-templates/skills/secret-handling/SKILL.md @@ -8,7 +8,7 @@ source: earned (issue #267 — credential leak incident) ## Context -Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), Scribe auto-commits them to git, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. +Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), they get committed with the team state or persisted by the state backend, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. ## Patterns @@ -55,9 +55,11 @@ Spawned agents have read access to the entire repository, including `.env` files - Architecture notes: "App uses JWT auth — token stored in session" - Schema documentation: "Requires OPENAI_API_KEY, GITHUB_TOKEN (see .env.example for format)" -### Scribe Pre-Commit Validation +### Pre-Commit Validation for `.squad/` -**Before committing `.squad/` changes, Scribe MUST:** +Scribe never commits (see its charter). This applies to whoever commits `.squad/` changes, an agent or the coordinator. + +**Before committing `.squad/` changes, the committer MUST:** 1. **Scan all staged files** for secret patterns (use regex table above) 2. **Check for prohibited file names** (don't commit `.env` even if manually staged) @@ -79,7 +81,7 @@ Spawned agents have read access to the entire repository, including `.env` files 4. **If no secrets detected:** - Proceed with commit as normal -**Implementation note for Scribe:** +**Implementation note:** - Run validation AFTER staging files, BEFORE calling `git commit` - Use PowerShell `Select-String` or `git diff --cached` to scan staged content - Fail loud — secret leaks are unacceptable, blocking the commit is correct behavior @@ -152,9 +154,9 @@ User: "It's a Postgres database, schema is in migrations/" "Database: Postgres (connection configured in .env). Schema defined in db/migrations/." ``` -### ✓ Correct: Scribe Pre-Commit Validation +### ✓ Correct: Pre-Commit Validation -**Scribe is about to commit:** +**An agent is about to commit `.squad/` changes:** ```powershell # Stage files @@ -196,5 +198,5 @@ git commit -F $msgFile - ❌ Committing first, scanning later — validation MUST happen before commit - ❌ Silently skipping secret detection — fail loud, never silent - ❌ Trusting agents to "know better" — enforce at multiple layers (prompt, hook, architecture) -- ❌ Writing secrets to "temporary" files in `.squad/` — Scribe commits ALL `.squad/` changes +- ❌ Writing secrets to "temporary" files in `.squad/` — `.squad/` changes get committed or persisted with the team state - ❌ Extracting "just the host" from a connection string — still leaks infrastructure topology diff --git a/.squad-templates/worktree-reference.md b/.squad-templates/worktree-reference.md index 564a45d52..589edb968 100644 --- a/.squad-templates/worktree-reference.md +++ b/.squad-templates/worktree-reference.md @@ -38,11 +38,11 @@ Squad and all spawned agents may be running inside a **git worktree** rather tha - `.squad/` files are **branch-local**. Each worktree works independently — no locking, no shared-state races. - When branches merge into main, `.squad/` state merges with them. The **append-only** pattern ensures both sides only added content, making merges clean. - A `merge=union` driver in `.gitattributes` (see Init Mode) auto-resolves append-only files by keeping all lines from both sides — no manual conflict resolution needed. -- The Scribe commits `.squad/` changes to the worktree's branch. State flows to other branches through normal git merge / PR workflow. +- `.squad/` changes are committed to the worktree's branch along with the work (Scribe does not commit; on non-local backends the runtime state tools persist mutable state). State flows to other branches through normal git merge / PR workflow. **Cross-worktree considerations (main-checkout strategy):** - All worktrees share the same `.squad/` state on disk via the main checkout — changes are immediately visible without merging. -- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, Scribe merge-and-commit steps will race on `decisions.md` and git index. Use only when a single session is active at a time. +- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, their decision merges and commits will race on `decisions.md` and the git index. Use only when a single session is active at a time. - Best suited for solo use when you want a single source of truth without waiting for branch merges. ### Worktree Lifecycle Management diff --git a/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md b/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md index 468cb3262..d88e02f72 100644 --- a/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md +++ b/packages/squad-cli/templates/skills/coordinator-source-of-truth/SKILL.md @@ -29,7 +29,7 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | | `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | | `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime, `squad watch` capabilities, and the retrospective facilitator (retro logs only); not Scribe | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/packages/squad-cli/templates/skills/e2e-template-testing/SKILL.md b/packages/squad-cli/templates/skills/e2e-template-testing/SKILL.md index d1b38d94e..37ac64e47 100644 --- a/packages/squad-cli/templates/skills/e2e-template-testing/SKILL.md +++ b/packages/squad-cli/templates/skills/e2e-template-testing/SKILL.md @@ -429,7 +429,7 @@ needs every row — pick the scenarios relevant to your modification. |---|----------|----------------|----------| | 1 | Basic init + task | Templates applied, agent spawned, work produced | — | | 2 | Cross-branch persistence | State survives `git checkout` (if state-backend) | — | -| 3 | Scribe behavior | Scribe commits to correct target | — | +| 3 | Scribe behavior | Scribe merges the decisions inbox into `decisions.md` through the state tools and commits nothing | — | | 4 | PR cleanliness | Feature branch PR has no leaked state files | — | | 5 | Migration path | Existing squad picks up new template behavior | — | | 6 | Edge case: empty repo | Init works in repo with single commit | — | diff --git a/packages/squad-cli/templates/skills/gh-auth-isolation/SKILL.md b/packages/squad-cli/templates/skills/gh-auth-isolation/SKILL.md index 5178573bb..d0f8dc2e5 100644 --- a/packages/squad-cli/templates/skills/gh-auth-isolation/SKILL.md +++ b/packages/squad-cli/templates/skills/gh-auth-isolation/SKILL.md @@ -177,7 +177,7 @@ git push https://personaluser:$token@github.com/personaluser/repo.git main - ❌ **Hardcoding tokens** in scripts, environment variables, or committed files. Use `gh auth token --user` to extract at runtime. - ❌ **Assuming the default `gh` auth works** for all repos. EMU accounts can't access personal repos and vice versa. - ❌ **Switching `gh auth login`** globally mid-session. This changes the default for ALL processes and can break parallel agents. -- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed by Scribe. Use `gh`'s credential store. +- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed with the team state. Use `gh`'s credential store. - ❌ **Ignoring token cleanup** after inline HTTPS pushes. Always reset the remote URL to avoid persisting tokens. - ❌ **Using `gh auth switch`** in multi-agent sessions. One agent switching affects all others sharing the shell. - ❌ **Mixing EMU and personal operations** in the same git clone. Use separate clones or explicit remote URLs per operation. diff --git a/packages/squad-cli/templates/skills/secret-handling/SKILL.md b/packages/squad-cli/templates/skills/secret-handling/SKILL.md index b6c6b31b6..dd9727ebc 100644 --- a/packages/squad-cli/templates/skills/secret-handling/SKILL.md +++ b/packages/squad-cli/templates/skills/secret-handling/SKILL.md @@ -8,7 +8,7 @@ source: earned (issue #267 — credential leak incident) ## Context -Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), Scribe auto-commits them to git, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. +Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), they get committed with the team state or persisted by the state backend, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. ## Patterns @@ -55,9 +55,11 @@ Spawned agents have read access to the entire repository, including `.env` files - Architecture notes: "App uses JWT auth — token stored in session" - Schema documentation: "Requires OPENAI_API_KEY, GITHUB_TOKEN (see .env.example for format)" -### Scribe Pre-Commit Validation +### Pre-Commit Validation for `.squad/` -**Before committing `.squad/` changes, Scribe MUST:** +Scribe never commits (see its charter). This applies to whoever commits `.squad/` changes, an agent or the coordinator. + +**Before committing `.squad/` changes, the committer MUST:** 1. **Scan all staged files** for secret patterns (use regex table above) 2. **Check for prohibited file names** (don't commit `.env` even if manually staged) @@ -79,7 +81,7 @@ Spawned agents have read access to the entire repository, including `.env` files 4. **If no secrets detected:** - Proceed with commit as normal -**Implementation note for Scribe:** +**Implementation note:** - Run validation AFTER staging files, BEFORE calling `git commit` - Use PowerShell `Select-String` or `git diff --cached` to scan staged content - Fail loud — secret leaks are unacceptable, blocking the commit is correct behavior @@ -152,9 +154,9 @@ User: "It's a Postgres database, schema is in migrations/" "Database: Postgres (connection configured in .env). Schema defined in db/migrations/." ``` -### ✓ Correct: Scribe Pre-Commit Validation +### ✓ Correct: Pre-Commit Validation -**Scribe is about to commit:** +**An agent is about to commit `.squad/` changes:** ```powershell # Stage files @@ -196,5 +198,5 @@ git commit -F $msgFile - ❌ Committing first, scanning later — validation MUST happen before commit - ❌ Silently skipping secret detection — fail loud, never silent - ❌ Trusting agents to "know better" — enforce at multiple layers (prompt, hook, architecture) -- ❌ Writing secrets to "temporary" files in `.squad/` — Scribe commits ALL `.squad/` changes +- ❌ Writing secrets to "temporary" files in `.squad/` — `.squad/` changes get committed or persisted with the team state - ❌ Extracting "just the host" from a connection string — still leaks infrastructure topology diff --git a/packages/squad-cli/templates/worktree-reference.md b/packages/squad-cli/templates/worktree-reference.md index 564a45d52..589edb968 100644 --- a/packages/squad-cli/templates/worktree-reference.md +++ b/packages/squad-cli/templates/worktree-reference.md @@ -38,11 +38,11 @@ Squad and all spawned agents may be running inside a **git worktree** rather tha - `.squad/` files are **branch-local**. Each worktree works independently — no locking, no shared-state races. - When branches merge into main, `.squad/` state merges with them. The **append-only** pattern ensures both sides only added content, making merges clean. - A `merge=union` driver in `.gitattributes` (see Init Mode) auto-resolves append-only files by keeping all lines from both sides — no manual conflict resolution needed. -- The Scribe commits `.squad/` changes to the worktree's branch. State flows to other branches through normal git merge / PR workflow. +- `.squad/` changes are committed to the worktree's branch along with the work (Scribe does not commit; on non-local backends the runtime state tools persist mutable state). State flows to other branches through normal git merge / PR workflow. **Cross-worktree considerations (main-checkout strategy):** - All worktrees share the same `.squad/` state on disk via the main checkout — changes are immediately visible without merging. -- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, Scribe merge-and-commit steps will race on `decisions.md` and git index. Use only when a single session is active at a time. +- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, their decision merges and commits will race on `decisions.md` and the git index. Use only when a single session is active at a time. - Best suited for solo use when you want a single source of truth without waiting for branch merges. ### Worktree Lifecycle Management diff --git a/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md b/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md index 468cb3262..d88e02f72 100644 --- a/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md +++ b/packages/squad-sdk/templates/skills/coordinator-source-of-truth/SKILL.md @@ -29,7 +29,7 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | | `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | | `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime, `squad watch` capabilities, and the retrospective facilitator (retro logs only); not Scribe | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/packages/squad-sdk/templates/skills/e2e-template-testing/SKILL.md b/packages/squad-sdk/templates/skills/e2e-template-testing/SKILL.md index d1b38d94e..37ac64e47 100644 --- a/packages/squad-sdk/templates/skills/e2e-template-testing/SKILL.md +++ b/packages/squad-sdk/templates/skills/e2e-template-testing/SKILL.md @@ -429,7 +429,7 @@ needs every row — pick the scenarios relevant to your modification. |---|----------|----------------|----------| | 1 | Basic init + task | Templates applied, agent spawned, work produced | — | | 2 | Cross-branch persistence | State survives `git checkout` (if state-backend) | — | -| 3 | Scribe behavior | Scribe commits to correct target | — | +| 3 | Scribe behavior | Scribe merges the decisions inbox into `decisions.md` through the state tools and commits nothing | — | | 4 | PR cleanliness | Feature branch PR has no leaked state files | — | | 5 | Migration path | Existing squad picks up new template behavior | — | | 6 | Edge case: empty repo | Init works in repo with single commit | — | diff --git a/packages/squad-sdk/templates/skills/gh-auth-isolation/SKILL.md b/packages/squad-sdk/templates/skills/gh-auth-isolation/SKILL.md index 5178573bb..d0f8dc2e5 100644 --- a/packages/squad-sdk/templates/skills/gh-auth-isolation/SKILL.md +++ b/packages/squad-sdk/templates/skills/gh-auth-isolation/SKILL.md @@ -177,7 +177,7 @@ git push https://personaluser:$token@github.com/personaluser/repo.git main - ❌ **Hardcoding tokens** in scripts, environment variables, or committed files. Use `gh auth token --user` to extract at runtime. - ❌ **Assuming the default `gh` auth works** for all repos. EMU accounts can't access personal repos and vice versa. - ❌ **Switching `gh auth login`** globally mid-session. This changes the default for ALL processes and can break parallel agents. -- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed by Scribe. Use `gh`'s credential store. +- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed with the team state. Use `gh`'s credential store. - ❌ **Ignoring token cleanup** after inline HTTPS pushes. Always reset the remote URL to avoid persisting tokens. - ❌ **Using `gh auth switch`** in multi-agent sessions. One agent switching affects all others sharing the shell. - ❌ **Mixing EMU and personal operations** in the same git clone. Use separate clones or explicit remote URLs per operation. diff --git a/packages/squad-sdk/templates/skills/secret-handling/SKILL.md b/packages/squad-sdk/templates/skills/secret-handling/SKILL.md index b6c6b31b6..dd9727ebc 100644 --- a/packages/squad-sdk/templates/skills/secret-handling/SKILL.md +++ b/packages/squad-sdk/templates/skills/secret-handling/SKILL.md @@ -8,7 +8,7 @@ source: earned (issue #267 — credential leak incident) ## Context -Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), Scribe auto-commits them to git, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. +Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), they get committed with the team state or persisted by the state backend, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. ## Patterns @@ -55,9 +55,11 @@ Spawned agents have read access to the entire repository, including `.env` files - Architecture notes: "App uses JWT auth — token stored in session" - Schema documentation: "Requires OPENAI_API_KEY, GITHUB_TOKEN (see .env.example for format)" -### Scribe Pre-Commit Validation +### Pre-Commit Validation for `.squad/` -**Before committing `.squad/` changes, Scribe MUST:** +Scribe never commits (see its charter). This applies to whoever commits `.squad/` changes, an agent or the coordinator. + +**Before committing `.squad/` changes, the committer MUST:** 1. **Scan all staged files** for secret patterns (use regex table above) 2. **Check for prohibited file names** (don't commit `.env` even if manually staged) @@ -79,7 +81,7 @@ Spawned agents have read access to the entire repository, including `.env` files 4. **If no secrets detected:** - Proceed with commit as normal -**Implementation note for Scribe:** +**Implementation note:** - Run validation AFTER staging files, BEFORE calling `git commit` - Use PowerShell `Select-String` or `git diff --cached` to scan staged content - Fail loud — secret leaks are unacceptable, blocking the commit is correct behavior @@ -152,9 +154,9 @@ User: "It's a Postgres database, schema is in migrations/" "Database: Postgres (connection configured in .env). Schema defined in db/migrations/." ``` -### ✓ Correct: Scribe Pre-Commit Validation +### ✓ Correct: Pre-Commit Validation -**Scribe is about to commit:** +**An agent is about to commit `.squad/` changes:** ```powershell # Stage files @@ -196,5 +198,5 @@ git commit -F $msgFile - ❌ Committing first, scanning later — validation MUST happen before commit - ❌ Silently skipping secret detection — fail loud, never silent - ❌ Trusting agents to "know better" — enforce at multiple layers (prompt, hook, architecture) -- ❌ Writing secrets to "temporary" files in `.squad/` — Scribe commits ALL `.squad/` changes +- ❌ Writing secrets to "temporary" files in `.squad/` — `.squad/` changes get committed or persisted with the team state - ❌ Extracting "just the host" from a connection string — still leaks infrastructure topology diff --git a/packages/squad-sdk/templates/worktree-reference.md b/packages/squad-sdk/templates/worktree-reference.md index 564a45d52..589edb968 100644 --- a/packages/squad-sdk/templates/worktree-reference.md +++ b/packages/squad-sdk/templates/worktree-reference.md @@ -38,11 +38,11 @@ Squad and all spawned agents may be running inside a **git worktree** rather tha - `.squad/` files are **branch-local**. Each worktree works independently — no locking, no shared-state races. - When branches merge into main, `.squad/` state merges with them. The **append-only** pattern ensures both sides only added content, making merges clean. - A `merge=union` driver in `.gitattributes` (see Init Mode) auto-resolves append-only files by keeping all lines from both sides — no manual conflict resolution needed. -- The Scribe commits `.squad/` changes to the worktree's branch. State flows to other branches through normal git merge / PR workflow. +- `.squad/` changes are committed to the worktree's branch along with the work (Scribe does not commit; on non-local backends the runtime state tools persist mutable state). State flows to other branches through normal git merge / PR workflow. **Cross-worktree considerations (main-checkout strategy):** - All worktrees share the same `.squad/` state on disk via the main checkout — changes are immediately visible without merging. -- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, Scribe merge-and-commit steps will race on `decisions.md` and git index. Use only when a single session is active at a time. +- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, their decision merges and commits will race on `decisions.md` and the git index. Use only when a single session is active at a time. - Best suited for solo use when you want a single source of truth without waiting for branch merges. ### Worktree Lifecycle Management diff --git a/templates/skills/coordinator-source-of-truth/SKILL.md b/templates/skills/coordinator-source-of-truth/SKILL.md index 468cb3262..d88e02f72 100644 --- a/templates/skills/coordinator-source-of-truth/SKILL.md +++ b/templates/skills/coordinator-source-of-truth/SKILL.md @@ -29,7 +29,7 @@ Files below marked as **"Derived / append-only"** are **mutable state** — agen | `.squad/agents/{name}/history.md` | **Derived / append-only.** Personal learnings. Never authoritative for enforcement. | Owning agent (append only); `squad nap` compresses it | Owning agent only | | `.squad/agents/{name}/history-archive.md` | **Derived / append-only.** Archived history entries. Preserved for reference. | `squad nap` (history compression) | Owning agent (read-only) | | `.squad/orchestration-log/` | **Derived / append-only.** Agent routing evidence. Never edited after write. | Legacy; no default writer (not Scribe) | All agents (read-only) | -| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime and `squad watch` capabilities (not Scribe) | All agents (read-only) | +| `.squad/log/` | **Derived / append-only.** Session logs. Diagnostic archive. Never edited after write. | Runtime, `squad watch` capabilities, and the retrospective facilitator (retro logs only); not Scribe | All agents (read-only) | | `.squad/templates/` | **Reference.** Format guides for runtime files. Not authoritative for enforcement. | Squad (Coordinator) at init | Squad (Coordinator) | | `.squad/rai/policy.md` | **Authoritative RAI policy.** Check categories, terminology standards, and opt-out rules. | Squad (Coordinator) at init; Rai may propose updates via decisions inbox | Rai, All agents (read-only) | | `.squad/rai/audit-trail.md` | **Derived / append-only.** RAI review evidence log. Redacted — never contains raw secrets or harmful content. | Rai (append only) | Rai, Squad (Coordinator) | diff --git a/templates/skills/e2e-template-testing/SKILL.md b/templates/skills/e2e-template-testing/SKILL.md index d1b38d94e..37ac64e47 100644 --- a/templates/skills/e2e-template-testing/SKILL.md +++ b/templates/skills/e2e-template-testing/SKILL.md @@ -429,7 +429,7 @@ needs every row — pick the scenarios relevant to your modification. |---|----------|----------------|----------| | 1 | Basic init + task | Templates applied, agent spawned, work produced | — | | 2 | Cross-branch persistence | State survives `git checkout` (if state-backend) | — | -| 3 | Scribe behavior | Scribe commits to correct target | — | +| 3 | Scribe behavior | Scribe merges the decisions inbox into `decisions.md` through the state tools and commits nothing | — | | 4 | PR cleanliness | Feature branch PR has no leaked state files | — | | 5 | Migration path | Existing squad picks up new template behavior | — | | 6 | Edge case: empty repo | Init works in repo with single commit | — | diff --git a/templates/skills/gh-auth-isolation/SKILL.md b/templates/skills/gh-auth-isolation/SKILL.md index 894955c1d..a3031c700 100644 --- a/templates/skills/gh-auth-isolation/SKILL.md +++ b/templates/skills/gh-auth-isolation/SKILL.md @@ -177,7 +177,7 @@ git push https://personaluser:$token@github.com/personaluser/repo.git main - ❌ **Hardcoding tokens** in scripts, environment variables, or committed files. Use `gh auth token --user` to extract at runtime. - ❌ **Assuming the default `gh` auth works** for all repos. EMU accounts can't access personal repos and vice versa. - ❌ **Switching `gh auth login`** globally mid-session. This changes the default for ALL processes and can break parallel agents. -- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed by Scribe. Use `gh`'s credential store. +- ❌ **Storing personal tokens in `.env`** or `.squad/` files. These get committed with the team state. Use `gh`'s credential store. - ❌ **Ignoring token cleanup** after inline HTTPS pushes. Always reset the remote URL to avoid persisting tokens. - ❌ **Using `gh auth switch`** in multi-agent sessions. One agent switching affects all others sharing the shell. - ❌ **Mixing EMU and personal operations** in the same git clone. Use separate clones or explicit remote URLs per operation. diff --git a/templates/skills/secret-handling/SKILL.md b/templates/skills/secret-handling/SKILL.md index b6c6b31b6..dd9727ebc 100644 --- a/templates/skills/secret-handling/SKILL.md +++ b/templates/skills/secret-handling/SKILL.md @@ -8,7 +8,7 @@ source: earned (issue #267 — credential leak incident) ## Context -Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), Scribe auto-commits them to git, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. +Spawned agents have read access to the entire repository, including `.env` files containing live credentials. If an agent reads secrets and writes them to `.squad/` files (decisions, logs, history), they get committed with the team state or persisted by the state backend, exposing them in remote history. This skill codifies absolute prohibitions and safe alternatives. ## Patterns @@ -55,9 +55,11 @@ Spawned agents have read access to the entire repository, including `.env` files - Architecture notes: "App uses JWT auth — token stored in session" - Schema documentation: "Requires OPENAI_API_KEY, GITHUB_TOKEN (see .env.example for format)" -### Scribe Pre-Commit Validation +### Pre-Commit Validation for `.squad/` -**Before committing `.squad/` changes, Scribe MUST:** +Scribe never commits (see its charter). This applies to whoever commits `.squad/` changes, an agent or the coordinator. + +**Before committing `.squad/` changes, the committer MUST:** 1. **Scan all staged files** for secret patterns (use regex table above) 2. **Check for prohibited file names** (don't commit `.env` even if manually staged) @@ -79,7 +81,7 @@ Spawned agents have read access to the entire repository, including `.env` files 4. **If no secrets detected:** - Proceed with commit as normal -**Implementation note for Scribe:** +**Implementation note:** - Run validation AFTER staging files, BEFORE calling `git commit` - Use PowerShell `Select-String` or `git diff --cached` to scan staged content - Fail loud — secret leaks are unacceptable, blocking the commit is correct behavior @@ -152,9 +154,9 @@ User: "It's a Postgres database, schema is in migrations/" "Database: Postgres (connection configured in .env). Schema defined in db/migrations/." ``` -### ✓ Correct: Scribe Pre-Commit Validation +### ✓ Correct: Pre-Commit Validation -**Scribe is about to commit:** +**An agent is about to commit `.squad/` changes:** ```powershell # Stage files @@ -196,5 +198,5 @@ git commit -F $msgFile - ❌ Committing first, scanning later — validation MUST happen before commit - ❌ Silently skipping secret detection — fail loud, never silent - ❌ Trusting agents to "know better" — enforce at multiple layers (prompt, hook, architecture) -- ❌ Writing secrets to "temporary" files in `.squad/` — Scribe commits ALL `.squad/` changes +- ❌ Writing secrets to "temporary" files in `.squad/` — `.squad/` changes get committed or persisted with the team state - ❌ Extracting "just the host" from a connection string — still leaks infrastructure topology diff --git a/templates/worktree-reference.md b/templates/worktree-reference.md index 564a45d52..589edb968 100644 --- a/templates/worktree-reference.md +++ b/templates/worktree-reference.md @@ -38,11 +38,11 @@ Squad and all spawned agents may be running inside a **git worktree** rather tha - `.squad/` files are **branch-local**. Each worktree works independently — no locking, no shared-state races. - When branches merge into main, `.squad/` state merges with them. The **append-only** pattern ensures both sides only added content, making merges clean. - A `merge=union` driver in `.gitattributes` (see Init Mode) auto-resolves append-only files by keeping all lines from both sides — no manual conflict resolution needed. -- The Scribe commits `.squad/` changes to the worktree's branch. State flows to other branches through normal git merge / PR workflow. +- `.squad/` changes are committed to the worktree's branch along with the work (Scribe does not commit; on non-local backends the runtime state tools persist mutable state). State flows to other branches through normal git merge / PR workflow. **Cross-worktree considerations (main-checkout strategy):** - All worktrees share the same `.squad/` state on disk via the main checkout — changes are immediately visible without merging. -- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, Scribe merge-and-commit steps will race on `decisions.md` and git index. Use only when a single session is active at a time. +- **Not safe for concurrent sessions.** If two worktrees run sessions simultaneously, their decision merges and commits will race on `decisions.md` and the git index. Use only when a single session is active at a time. - Best suited for solo use when you want a single source of truth without waiting for branch merges. ### Worktree Lifecycle Management diff --git a/test/ci/scribe-template.test.ts b/test/ci/scribe-template.test.ts index 0545d42d6..7a98570a3 100644 --- a/test/ci/scribe-template.test.ts +++ b/test/ci/scribe-template.test.ts @@ -92,6 +92,14 @@ describe('Scribe contract — every prompt surface agrees with the charter', () 'cross-agent context sharing', 'Scribe / Logger', 'Scribe or designated', + // The charter forbids Scribe from committing state; commits belong to whoever commits the work. + 'Scribe commits', + 'Scribe auto-commits', + 'committed by Scribe', + 'Scribe Pre-Commit', + 'Scribe is about to commit', + 'Scribe merge-and-commit', + 'Implementation note for Scribe', ]; const files = (readdirSync(resolve(ROOT, '.squad-templates'), { recursive: true }) as string[]) .map((f) => `.squad-templates/${f.replace(/\\/g, '/')}`) @@ -103,6 +111,16 @@ describe('Scribe contract — every prompt surface agrees with the charter', () } }); + it('lets the retrospective facilitator write the retro log the retro gate waits for', () => { + // retro-enforcement blocks work until the facilitator (never Scribe) writes to .squad/log/, + // so the source-of-truth writer table must allow that facilitator to write there. + expect(read('.squad-templates/skills/retro-enforcement/SKILL.md')).toMatch(/facilitator agent\*\* \(the Lead or a designated member, never Scribe\)[\s\S]*Wait for the log file\*\* to be written to `\.squad\/log\/`/); + const logRow = read('.squad-templates/skills/coordinator-source-of-truth/SKILL.md') + .split(/\r?\n/).find((line) => line.startsWith('| `.squad/log/` |')) ?? ''; + expect(logRow).toContain('retrospective facilitator'); + expect(logRow).toContain('not Scribe'); + }); + it('the gh-aw builtin charter matches the template charter', () => { expect(read('workflows/shared/builtins/scribe-charter.md')).toBe(read('.squad-templates/scribe-charter.md')); }); From 62d86943d4eb5634f183873360eec91101327d5d Mon Sep 17 00:00:00 2001 From: Jose Luis Latorre Millas Date: Tue, 10 Nov 2026 22:18:49 +0100 Subject: [PATCH 3/3] test: update the Copilot projection snapshot for the Scribe template changes The projection guard (#2438) pins every file squad init + upgrade writes. This PR changes five of them on purpose: squad.agent.md and the agent-collaboration, coordinator-init-mode, coordinator-source-of-truth and secret-handling skills. --- .../host-projection-regression-guards.test.ts.snap | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/__snapshots__/host-projection-regression-guards.test.ts.snap b/test/__snapshots__/host-projection-regression-guards.test.ts.snap index 61bab6d33..eaa379a2b 100644 --- a/test/__snapshots__/host-projection-regression-guards.test.ts.snap +++ b/test/__snapshots__/host-projection-regression-guards.test.ts.snap @@ -4,11 +4,11 @@ exports[`host projection regression guards (#2438) > guard 1: the Copilot projec { ".copilot/mcp-config.json": "c68ab872f9f9b0a4ff12b221ee8bccb6dfec1bf1b886f05971935d5bc48b33e6", ".gitattributes": "fe8886d03bd8d8c7fb0b274cb8748fe4c97b08ce8b55c2aa72a2e173a0235ce3", - ".github/agents/squad.agent.md": "b5160cf1f21a717653cfd0c068f7b405fe8fb40c86c47882b105a0e383cae7fa", - ".github/skills/agent-collaboration/SKILL.md": "e1943766f6aa5efeb145f22d1583f5b38d4d8a7109ae17f085ec064dada4b9bf", - ".github/skills/coordinator-init-mode/SKILL.md": "3e74448a48372968a7d14c43e7461bed1aee968073461341a6e33d57de0f85e1", + ".github/agents/squad.agent.md": "d11b650a12c3bf2c72e78a7202c484358983a6b9ff4e4d1f1fd646808665bb86", + ".github/skills/agent-collaboration/SKILL.md": "be2353a077d5efb7d61f059c978c78e9b536cab357d0d0c965b54eb163a47bb2", + ".github/skills/coordinator-init-mode/SKILL.md": "8b65780dacdf95144cc64fedba1ca22c7a939875f94e3e6562b84301bea53a93", ".github/skills/coordinator-response-mode/SKILL.md": "0be5f6ac5e3ad7c8b818770a72fa8bf3693196c23c9bba1ae7675caabd73e8c1", - ".github/skills/coordinator-source-of-truth/SKILL.md": "d541d499104627392f45319bfdd85d8d77693d4e7c1bed0b616e985bd33fd0b9", + ".github/skills/coordinator-source-of-truth/SKILL.md": "26da4bfe933fba681c679760203e2d7df113bca9290fbe30732dbfc27cb0f171", ".github/skills/cross-squad-communication/SKILL.md": "c8d7744cd194cf070ba53537586b6a4f19dfe09024b6cc18ffd85bd65f5aed70", ".github/skills/cross-squad/SKILL.md": "8f62616ee39835c8e2954cb9327cf813cf1c6d5f6d8652773c82f042aa076270", ".github/skills/error-recovery/SKILL.md": "a6bc62ea076cfbbd61b8348fc269014a87400c7b69c8d7cb14c1469f0ce87977", @@ -16,7 +16,7 @@ exports[`host projection regression guards (#2438) > guard 1: the Copilot projec ".github/skills/iterative-retrieval/SKILL.md": "a1ac94cbaed7ddbf49cc452f4045521d33a0303458c63c356bd523941ee4f22c", ".github/skills/reflect/SKILL.md": "56a68807c843c9d4c1ab837ce8c91c5469c595443b626c34aabaf820732aeaba", ".github/skills/reviewer-protocol/SKILL.md": "c262486a165fc9f5749c4ab96042dc6e549b43ad8a2d40a5b2ba05a79b4ea8fc", - ".github/skills/secret-handling/SKILL.md": "b59ecbc69e0e5d295f0dcf6a90cd555e86c244eaacef786a753fca0e78ea8765", + ".github/skills/secret-handling/SKILL.md": "5860413816b3a3b9c854690ca1f515307e4670f0a6983baf4a67806f6d68a251", ".github/skills/session-recovery/SKILL.md": "54a7c1feba619de57cc212774406331fd53447d48d565430489a6202a0e6b67a", ".github/skills/squad-conventions/SKILL.md": "7e1a53f10ceed067e38de48865bfc212deb1fdb04fee65038a7a135753e25c7c", ".github/skills/squad-help/SKILL.md": "d2696395847e146dffc88668890adbd4104b3a9fe72be3fb47d773511eb9a4f8",