chore: promote v0.10.1 dev → main + v0.10 stabilisation blog post#1313
Open
tamirdresher wants to merge 42 commits into
Open
chore: promote v0.10.1 dev → main + v0.10 stabilisation blog post#1313tamirdresher wants to merge 42 commits into
tamirdresher wants to merge 42 commits into
Conversation
…er#1222) The Fact Checker role landed in v0.10.0 (bradygaster#789) with catalog entry, charter template, skill, AGENT_TEMPLATES map entry, and template manifest entry — but was never wired into the user-facing onboarding flow. Users running 'squad init' got Scribe/Ralph/Rai but never saw Fact Checker as a default or cast option. This mirrors how Rai was wired: - init.ts: adds 'fact-checker' to the default agents: array passed to sdkInitSquad() - cast.ts: adds factCheckerMember(), factCheckerCharter(), hasFactChecker branches in castTeam(), and the roster banner line Smoke-tested locally: 'squad init' in a clean repo now produces .squad/agents/fact-checker/charter.md alongside scribe/ralph/Rai. Closes bradygaster#1222 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ygaster#1222) Extends the bradygaster#1222 fix to the third code path. \squad upgrade\ was intentionally silent on agents (preserves user state). For users upgrading from v0.9.x or earlier (no Rai) or v0.10.0 (no fact-checker), this means they'd never get the built-in agents unless they re-ran \squad init\ (which would overwrite other state). Adds \�nsureBuiltinAgents()\ to \ unEnsureChecks()\. Idempotent — only scaffolds when the agent directory is absent. Never overwrites existing charters or history files. Sources content from the shipped \ emplates/{Rai,fact-checker}-charter.md\ templates (already present via TEMPLATE_MANIFEST). Scribe and Ralph are intentionally NOT scaffolded by upgrade — they predate this fix in every squad, and their charters are inlined in cast.ts (no shipped template file). Smoke tested locally: - Set up a simulated v0.9.4 squad (scribe + ralph only) - Ran \squad upgrade\ → 'scaffolded 2 built-in agent(s): Rai, fact-checker' - Ran upgrade again → no re-scaffold (idempotent) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…hecker-auto-scaffold fix: auto-scaffold Fact Checker agent during init and cast (bradygaster#1222)
bradygaster#1192) The Copilot CLI post-v1.0.54 changed the permission handler contract to expect 'approve-once' instead of 'approved'. Update the handler, type definition, and error hint to match the new contract. Closes bradygaster#1191 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ad CLI (bradygaster#1207) * feat: Squad.Agents.AI community NuGet for MAF integration Squad CLI as Microsoft.Extensions.AI IChatClient, composing GitHub.Copilot.SDK via AsAIAgent() from Microsoft.Agents.AI.GitHub.Copilot 1.7.0-preview. Closes Track A of the Q1-Q7 design lock (see tamresearch1 .squad/decisions.md Decisions 441, 443, 444, 447). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: add PR body for #3 * fix(SquadAgent): inherit AIAgent (was IChatClient force-cast) - SquadAgent now properly inherits from Microsoft.Agents.AI.AIAgent - Removed (IChatClient)(object)agent force-cast - Overrides all AIAgent abstract members (CreateSessionCoreAsync, RunCoreAsync, etc.) - DI registration now registers AIAgent (not IChatClient) - README updated to use AIAgent.RunAsync API - No more abstraction inversion; AIAgent is the correct layer Fixes the architectural error identified by Tamir. * docs(SquadAgent): rewrite README — prerequisites, Hello World, troubleshooting, preview callout Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat(SquadAgent): GitHubTokenProvider callback + redact options ToString Adds async token provider pattern for production scenarios (KeyVault/MSI integration). - GitHubTokenProvider property takes precedence over GitHubToken - GitHubToken marked [JsonIgnore] to prevent serialization leaks - SquadAgentOptions.ToString() redacts GitHubToken field - Updated CreateCopilotClient to resolve token from provider first Mitigates P0 #3: token leakage via ILogger structured-log calls, IOptions snapshots, and serializers. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(SquadAgent): document GitHubTokenProvider callback for production token management Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(SquadAgent): bind ConnectionStrings__squad via IConfigureOptions + add smoke tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(README): replace removed WithTeamRoot with positional teamRoot ctor WithTeamRoot was deleted in commit 35767c90 in favor of mandatory positional teamRoot constructor argument on AddSquad. The Aspire example in the Squad.Agents.AI README still showed the old fluent API, which would now fail at compile time for anyone copy-pasting. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(squad-agents-ai): add routing integration tests Closes the routing-verification gap identified during squad-squad onboarding: the API surface existed but routing semantics weren't functionally tested. New tests verify persona pass-through, boundary-instruction injection on first turn, WorkingDirectory isolation (Decision 452a), and CopilotClientOptions-based routing (Decision 447). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci(squad-agents-ai): add .NET build/test/pack workflow PR #3 CI was Node/docs-only — adding the .NET gate so green actually reflects the package code. Matrix on ubuntu + windows, restore/build/test/pack, uploads TestResults and nupkg artifacts. Closes the build-verification gap identified during squad-squad onboarding (see .squad/decisions.md adoption record, 2026-06-02). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci(squad-agents-ai): NuGet publish workflow + Dependabot config - .github/workflows/squad-agents-ai-release.yml: workflow_dispatch and tag-driven publish to nuget.org with --skip-duplicate idempotency, fail-fast on missing NUGET_API_KEY secret, optional GitHub Release on tag - .github/dependabot.yml: nuget (src + test) + github-actions, weekly, M.A.AI major allowed, OpenTelemetry major deferred (per Decision 602) Closes the release-pipeline + supply-chain-tracking gaps identified during squad-squad onboarding. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs(squad-agents-ai): release-ready docs + .csproj packaging metadata - README updates / XML docs on public surface - CHANGELOG.md with [0.1.0-preview] - 2026-06-02 entry - .csproj: Description, RepositoryUrl, Authors, PackageTags, PackageReadmeFile - Verified via dotnet pack — .nupkg contains README, LICENSE, xml-docs Closes the docs-readiness gap for v0.1-preview publish. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci(squad-agents-ai): switch release triggers to dev/main branch-driven Per Tamir's release-strategy directive (decisions.md 2026-06-02): - dev merges → prerelease publish (suffix scheme mirrors Squad CLI) - main merges → stable publish - workflow_dispatch retained as manual escape hatch - tag-driven trigger removed (branches are the source of truth) Version derivation pattern adapted from the Squad CLI's existing release workflow. --skip-duplicate retained for idempotent reruns. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs+fix: PR #3 review pass — hygiene, XML docs, cliArgs, multi-named connections - Rewrite the package README and PR validation flow around the AIAgent surface and ambient Copilot authentication. - Keep public docs free of internal process references and remove obsolete deferral language. - Preserve connection-string cliArgs through CopilotClientOptions and cover the behavior with a routing test. - Add named connection-string lookup via AddSquadAgent("name") using ConnectionStrings:squad-{name}. - Document the new public overloads and verify the package builds without warnings. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: Round 2 — keyed DI, BYOK delegate, routing gate, security hardening - Add ConfigureCopilotClient delegate on SquadAgentOptions for BYOK - Add routing gate: snapshot/restore Cwd/CliPath/CliArgs after delegate (Picard C1) - Add 4 AddKeyedSquadAgent overloads with .NET 8+ keyed DI - Fix Environment credential leak: [JsonIgnore] on Environment, GitHubTokenProvider, ConfigureCopilotClient - ToString() redacts token-pattern keys (TOKEN/KEY/SECRET/HMAC/PASSWORD/CREDENTIAL) - Add 21 new tests (43 total): security redaction, keyed DI, BYOK routing gate - Update README: streaming, keyed DI, BYOK, security sections Complies with: Picard C1-C4, Worf SC-1 through SC-8. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * feat: add Squad.Agents.AI sample app demonstrating DI, keyed DI, BYOK, and streaming - samples/squad-agents-ai-sample/Program.cs: four runnable flows Flow 1 -- AddSquadAgent + RunAsync (basic DI) Flow 2 -- AddKeyedSquadAgent x2 + GetRequiredKeyedService<SquadAgent> Flow 3 -- ConfigureCopilotClient delegate (BYOK token + env var injection) Flow 4 -- RunStreamingAsync with await foreach token-by-token output - samples/squad-agents-ai-sample/Squad.Agents.AI.Sample.csproj: net10.0, project reference to src/Squad.Agents.AI, Microsoft.Extensions.Hosting 10.0.0 - samples/squad-agents-ai-sample/README.md: prerequisites, run commands, per-flow walkthrough, troubleshooting table - .github/workflows/squad-agents-ai-ci.yml: adds paths trigger and restore + build steps for the sample (no run step -- requires live CLI) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(Squad.Agents.AI): co-locate sample under src/ and consolidate README - Moves the sample app from samples/squad-agents-ai-sample/ to src/Squad.Agents.AI/samples/Squad.Agents.AI.Sample/ so it lives alongside the package it demonstrates. - Folds the sample's standalone README into the package README, giving consumers one canonical doc for both the API and the runnable demo. - Adds <Compile Remove="samples/**/*.cs" /> to Squad.Agents.AI.csproj so the library's wildcard glob does not pick up Program.cs in the co-located samples subdirectory. - Updates the .csproj project reference, and CI workflow paths to match the new layout. - Verified end-to-end: dotnet build, dotnet test (43/43 passing), and a sample sanity-check run (clear CLI-not-found error, no stack trace). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(Squad.Agents.AI): remove outdated draft PR body file The standalone pr-body.md was an early draft authored before the live PR description took its final shape. The PR body on GitHub is the canonical source; this file is dead weight and would confuse maintainers reviewing the diff. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(Squad.Agents.AI): address PR bradygaster#1207 reviewer feedback (12 items) - Snapshot CliArgs by value, not reference, so in-place mutation by SDK consumers is also caught by the routing guard. - Validate name/connectionName/serviceKey is non-empty in all DI registration overloads; previously null/whitespace produced invalid connection-string keys. - Replace ghp_-prefixed placeholder in the sample with a clearly-fake token to avoid tripping secret-scanning and to remove a real-token lookalike. - Remove brittle 'PR #3' references from README and CHANGELOG; describe the feature without tying to a specific PR thread. - Update NuGet metadata and README links to point to bradygaster/squad (canonical repo) instead of the tamirdresher fork. - Multi-target the test project to match the package's target framework set so CI exercises every framework the package ships against. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * refactor(Squad.Agents.AI): adopt DelegatingAIAgent base + MAF ctor pattern (PR bradygaster#1207 r2) Addresses westey-m's review feedback: - Extend Microsoft.Agents.AI.DelegatingAIAgent — drops ~70 lines of manual Core* overrides; pass-through is provided by the base class. - Adopt MAF constructor pattern: \(string squadFolderPath, SquadAgentOptions? options = null, ILoggerFactory? loggerFactory = null)\. Required settings on the constructor, options optional, ILoggerFactory stays on ctor for DI injection. - Routing-guard, IAsyncDisposable, and security posture preserved. - Add Squad.Agents.AI.slnx solution for easy IDE open. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Reno (Copilot) <reno@clawpilotsquad.dev> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: tamirdresher <tamirdresher@users.noreply.github.com>
bradygaster#1240) Replace the long-lived NUGET_API_KEY repo secret with NuGet/login@v1 OIDC token exchange (1-hour API key) per the modern Trusted Publishing flow: https://learn.microsoft.com/nuget/nuget-org/trusted-publishing Why --- - No long-lived credentials stored in the repo. - Token is scoped to this workflow + repo + branch via the OIDC subject claim and the Trusted Publishing policy registered on nuget.org. - Eliminates the chicken-and-egg between needing admin to set NUGET_API_KEY and needing the package live to validate the workflow. What changed ------------ - Add `id-token: write` to the publish job (required for OIDC). - Drop the `Verify NuGet API key` step. - Drop the `--api-key ` reference to secrets.NUGET_API_KEY. - Add `NuGet/login@v1` step that exchanges the OIDC token for a short-lived API key, exposed via `steps.nuget-login.outputs.NUGET_API_KEY`. - Add a fail-fast check for the new `vars.NUGET_USER` repository variable (non-sensitive; the nuget.org profile name that performs the exchange). - Update the file header documentation to reflect the new flow and link to the Trusted Publishing setup page. Required configuration before first publish ------------------------------------------- 1. Create the `Squad` organization on nuget.org and add owners. 2. Configure a Trusted Publishing policy at https://www.nuget.org/account/trusted-publishing owned by the Squad org: Repository Owner: bradygaster Repository: squad Workflow File: squad-agents-ai-release.yml Environment: (empty) 3. Set repository variable NUGET_USER (Settings → Secrets and variables → Actions → Variables) to a Squad-org-member's nuget.org profile name (NOT email). Variable, not secret — the username is non-sensitive. Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…est (bradygaster#1252) Squad.Agents.AI 0.1.0-preview.2 calls `CopilotClient.AsAIAgent(instructions, name)` which leaves `SessionConfig.OnPermissionRequest` unset. The first call to `SquadAgent.CreateSessionAsync()` therefore throws: System.ArgumentException: An OnPermissionRequest handler is required when creating a session. For example, to allow all permissions, use CreateSessionAsync(new() { OnPermissionRequest = PermissionHandler.ApproveAll }); There was no public way for consumers to fix it from the outside — `ConfigureCopilotClient` only exposes `CopilotClientOptions`, not the per-session `SessionConfig` that owns the permission handler. What changed ------------ - `SquadAgent` now switches to the `AsAIAgent(client, sessionConfig, ...)` overload and constructs a `SessionConfig` with: - `OnPermissionRequest = PermissionHandler.ApproveAll` (sensible default for a host-process Squad adapter; the host already chose to instantiate Squad and is responsible for sandboxing). - `WorkingDirectory` defaulting to the resolved `Cwd` / `SquadFolderPath`. - `SystemMessage = new SystemMessageConfig { Content = Instructions }` when `SquadAgentOptions.Instructions` is set. - `SquadAgentOptions.ConfigureSession: Action<SessionConfig>?` is new — runs after Squad applies its defaults so a consumer can swap in a stricter permission handler, pin the model, restrict tools, etc. Tests ----- - New `SquadAgentSessionConfigTests` (4 cases) exercising the new surface: `ConfigureSession` is settable, runs against the live SessionConfig, can replace the permission handler, and can set `AvailableTools`. - All existing 43 tests still pass per TFM (141 total across net8/9/10). Verified -------- - The end-to-end consumer smoke test in `C:\Users\tamirdresher\source\repos\squad-agents-ai-consume-test` previously had to fall back to the raw SDK because of the missing handler. With this change, `SquadAgent.CreateSessionAsync()` returns successfully and `RunAsync` drives real 3-turn conversations against `.squad/`-init'd teams. Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…O works (bradygaster#1259) * Squad.Agents.AI: bump to MAF 1.10.0-rc1 / SDK 1.0.0 GA — file-IO now works Microsoft.Agents.AI.GitHub.Copilot bumped from 1.7.0-preview to 1.10.0-rc1, which transitively brings GitHub.Copilot.SDK 1.0.0 GA. SDK 1.0.0 reshaped CopilotClientOptions and SessionConfig (the breaking namespace + property renames are mirrored below), but in return Copilot CLI 1.0.61 talks to the SDK over the new ACP-style protocol — meaning the agent's view/grep/powershell tools finally work end-to-end without 'permission errors' or 'content exclusion policy' hallucinations. SDK 1.0.0 API migrations applied: * Namespace GitHub.Copilot.SDK -> GitHub.Copilot. * CopilotClientOptions.Cwd -> WorkingDirectory. * CopilotClientOptions.CliPath + .CliArgs collapsed into a single CopilotClientOptions.Connection (RuntimeConnection). We now build the Connection via RuntimeConnection.ForStdio(CliPath, CliArgs) only when the consumer supplied either a custom CLI path or extra CLI args; otherwise the SDK's default child-process connection is used and the bundled copilot.exe (downloaded by the SDK's build/ targets) is invoked. * SessionConfig.ConfigDir -> SessionConfig.ConfigDirectory. * PermissionRequestHandler is no longer a named delegate type; we use type inference where the test code referenced it. Public Squad.Agents.AI surface is intentionally unchanged: SquadAgentOptions still exposes Cwd, CliPath, CliArgs, ConfigureSession, ConfigureCopilotClient. We translate to the SDK 1.0.0 shape internally. Routing gate (Picard Condition 1 / Worf SC-3) updated to snapshot and restore WorkingDirectory + Connection instead of the old Cwd / CliPath / CliArgs trio. A delegate that REPLACES Connection (e.g. via RuntimeConnection.ForStdio(...)) is reverted, mirroring the previous CliPath / CliArgs hijack tests. Verified end-to-end against a real .squad-initialised team root: the coordinator successfully reads .squad/team.md and enumerates every cast member with their role. The dotnet test suite passes 46/46 across net8.0, net9.0, and net10.0 (-1 vs baseline because the old CliPath and CliArgs hijack tests collapsed into a single Connection hijack test, which is the right granularity for SDK 1.0.0). Version bumped 0.1.0-preview -> 0.2.0 to surface the MAF/SDK transitive bump. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Copilot review feedback (bradygaster#1259) - Remove duplicate 'using GitHub.Copilot' in SquadAgentSessionConfigTests (regex replace inadvertently doubled the directive when migrating from the old GitHub.Copilot.SDK namespace). - Drop hardcoded teamRoot override I left behind in the sample Program.cs during the CLI-not-found debug session. The sample now correctly reads SQUAD_TEAM_ROOT (or falls back to CWD) as documented. - Fix mismatched comment in SquadAgent: the SDK-protocol section now correctly references --allow-all (matching the flag actually injected in CreateCopilotClient), not the narrower --allow-all-tools. - Detect more existing permission-opening flags before injecting our default --allow-all so a host that opts in via --allow-all-paths, --allow-all-urls, or the omnibus --yolo no longer gets --allow-all prepended on top. Comparison is now case-insensitive. Updated the connection-string test that asserted the old over-eager behavior. Also add .vs/, *.user, *.userprefs to .gitignore so VS solution junk doesn't surface in git status. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…#1212 (bradygaster#1258) - Workflow permissions: add issues: write to squad-pr-nudge, squad-impact, and squad-repo-health workflows that call issues.createComment - Logic bug: fix ahead_by → behind_by in pr-nudge stale branch check - Logic bug: fix PR_LABELS fallback producing string instead of null - Script fix: check legacy statuses for failure/error in checkCIStatus() - Script fix: truncation row column count mismatch in pr-readiness.mjs - Script fix: validate JSON.parse result is array before using as labels - Script fix: isNodeBuiltin now validates node: prefix against known builtins - YAML escaping: use JSON.stringify for skill descriptions in apm.yml Closes bradygaster#1213 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…line (bradygaster#1251) - Expose memory.classify, memory.write, memory.search, memory.promote, memory.delete, memory.audit through the squad_state MCP server (bradygaster#1244) - Pin squad_state to user-level ~/.copilot/mcp-config.json during init/upgrade for external `copilot -p` mode compatibility (bradygaster#1247) - Update squad.agent.md directive-capture and decision-recording instructions to route through memory.write instead of raw squad_state_write to the drop-box (bradygaster#1246) Closes bradygaster#1244 Closes bradygaster#1247 Closes bradygaster#1246 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…skills/ (bradygaster#1260) The CLI and SDK write skills to .copilot/skills/ by default, but docs still referenced .squad/skills/. Update all documentation to use the canonical .copilot/skills/ path and add a note about legacy fallback. Closes bradygaster#1241 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…bradygaster#1262) Add an interactive prompt during squad init that asks users if they want to add @copilot (the GitHub Copilot coding agent) as an autonomous team member. If accepted, adds the Coding Agent section to team.md and copies copilot-instructions.md into the project. Non-interactive mode skips silently with a hint to run `squad copilot enable` later. Closes bradygaster#1147 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
bradygaster#1226) (bradygaster#1249) - Update all docs references from .squad/skills/ to .copilot/skills/ - Note that both paths are scanned at read time but .copilot/skills/ is write default - List all 6 git hooks (add pre-commit and post-commit to docs) - Correct 'read-only reference' claim about migrated files - Add recovery section for pre-commit hook refusal scenarios Closes bradygaster#1241 Closes bradygaster#1226 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…r#1265) Adds a typed OnSubagentTrace callback + OpenTelemetry ActivitySource so consumers can see subagent dispatch (the coordinator's 'task' tool spawning specialist sub-agents and their replies) without writing their own polymorphic dispatch over the raw GitHub.Copilot SessionEvent hierarchy. The previous 0.2.x surface required consumers to write the same boilerplate the aspire-squad-resource demo had to (CopilotSessionTraceMapper.cs): switch on every event subtype, unwrap subagent context, manage Activity lifetime. 0.3.0 makes that the SDK's job. New public surface: * SquadAgentOptions.OnSubagentTrace (Action<SquadAgentTraceEvent>) Set this to subscribe to subagent lifecycle (Selected / Started / Completed / Failed), assistant messages from coordinator AND subagents, tool start/complete, and SessionIdle. Setting OnSubagentTrace implicitly turns on SessionConfig.IncludeSubAgentStreamingEvents so subagent replies actually flow up to the parent session (otherwise they stay inside the subagent session and never reach the callback). * SquadAgentTraceEvent record — typed envelope (Kind, RawEventType, Timestamp, SdkAgentId, SubagentName, SubagentDisplayName, ToolCallId, Content, Success, RawEvent). Carries the original SessionEvent on RawEvent for advanced consumers but exposes everything else through neutral primitive types so the callback signature has no transitive dependency on GitHub.Copilot.SDK. * SquadAgentTraceEventKind enum — categorises the SessionEvent into the well-known cases that downstream observability surfaces want. * SquadAgentDiagnostics.ActivitySourceName ('Microsoft.Agents.AI.Squad') + SquadAgentDiagnostics.ActivitySource — one Activity per subagent dispatch is opened on SubagentStartedEvent and disposed on the matching SubagentCompletedEvent / SubagentFailedEvent, tagged with squad.subagent.name, squad.subagent.display_name, squad.subagent.sdk_agent_id, and squad.subagent.reply_preview (a short truncated copy of the subagent's assistant message). Hosts that .AddSource(SquadAgentDiagnostics.ActivitySourceName) on their OpenTelemetry tracer get these spans in their backend — the Aspire dashboard renders them in the trace view automatically. Internal: * SquadSubagentTraceMapper — wires SessionEvent -> SquadAgentTraceEvent and the Activity lifecycle. Held by SquadAgent and disposed during DisposeAsync to drain any subagent activities that never received a matching Completed event (e.g. session ended mid-dispatch). * InternalsVisibleTo=Squad.Agents.AI.Tests so the mapper can be unit tested directly without spinning a real CLI session. Tests: 54/54 passing across net8, net9, net10 (+8 new tests for the observability surface including Activity lifetime, tag propagation, mid-session disposal, and consumer-callback exception isolation). Verified end-to-end against the tamresearch1 Star Trek squad: the OnSubagentTrace callback observed two parallel subagent dispatches (Picard, Data), captured each of their replies attributed to the right SdkAgentId, and the matching 'squad.subagent Picard' / 'squad.subagent Data' OTel spans opened and closed cleanly with the reply tagged on each span. Version bumped 0.2.0 -> 0.3.0 to signal the new public surface. Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…mp (bradygaster#1266) After the v0.10.0 stable release on 2026-06-07, the root package-lock.json still recorded packages/squad-cli@0.9.6-preview.15 and packages/squad-sdk@0.9.6-preview.13 for the workspace entries. The package.json files were updated correctly during the release, but the lockfile workspace metadata was not regenerated. This causes `npm ci --ignore-scripts` to fail in the `sdk-exports-validation` CI job whenever package.json versions diverge from these stale lockfile entries (which happens on every build that runs `scripts/bump-build.mjs`). Confirmed on PR bradygaster#1257. This commit regenerates only the workspace version metadata (`packages/squad-cli` and `packages/squad-sdk`) — no dependency trees are touched. Verified locally on Windows + Node v23.5.0: - `npm ci --ignore-scripts` at repo root: ✅ exit 0 (was already passing on dev because root package.json/lockfile match; failure mode is the workspace-entry mismatch surfacing under specific build conditions) - `npm install --ignore-scripts`: no further drift produced - Full `npm test` suite: 6535 passed / 134 failed / 60 skipped — the 134 failures are all pre-existing Windows file-locking flakiness (EBUSY/ENOTEMPTY/hook-timeout); identical failure mode and similar count on the immediate pre-merge commit cc37a2f (125 failures pre-merge, 134 post-merge — diff is within flake noise). - Targeted re-run of the 5 "newly failing" files in isolation: 93/93 passing — confirms the bulk-run failures are concurrency-induced flakes, not regressions from the recent merges (bradygaster#1251, bradygaster#1258, bradygaster#1260, bradygaster#1262, bradygaster#1249). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ter#1267) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…1204) (bradygaster#1250) * fix: release pipeline version pinning (bradygaster#1203, bradygaster#1204) - Lower SDK dependency floor from >=0.10.0 to >=0.9.0 so the CLI tarball resolves against the last published SDK when current version isn't yet on the registry (Closes bradygaster#1203) - Add isLocalOrUnpublishedVersion guard so local dev builds and versions with build metadata (+) fall back to @insider instead of writing unresolvable version strings into MCP config (Closes bradygaster#1204) - Extend resolveSquadStateMcpSpec to short-circuit for build-metadata versions - Add CI step to verify SDK dependency is resolvable before CLI publish Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: reset accidentally-bumped version 0.10.0-build.2 -> 0.10.0 Pre-publish version guard rejects -build.N suffixes (release pipeline policy). The bump was made by an unintended local 'npm run build' run before commit. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamir.dresher@gmail.com> Co-authored-by: Copilot <tamirdresher@users.noreply.github.com>
* chore: include CHANGELOG.md in published npm tarball Add CHANGELOG.md to the files array in both squad-cli and squad-sdk package.json files so changelogs are included in published npm tarballs. This enables offline what's-new prompts and removes the need for GitHub API calls to show release notes. Closes bradygaster#1171 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore: reset accidentally-bumped versions to 0.10.0 Pre-publish version guard rejects -build.N suffixes (release pipeline policy). Both SDK and CLI package.json had -build.4 from a local 'npm run build' run before commit. --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamir.dresher@gmail.com> Co-authored-by: Copilot <tamirdresher@users.noreply.github.com>
…le connection-string lookup (bradygaster#1271) Two small but high-impact changes that remove ~30 lines of boilerplate from every consumer (Aspire and otherwise) and make the OpenTelemetry story self-explanatory. ## 1. EmitSubagentActivities (default true) — telemetry independent of callback Today, the per-subagent OpenTelemetry Activity emission is a side-effect of setting `OnSubagentTrace`. A host that just wants `squad.subagent {Name}` spans in their backend has to wire a callback they don't need. `Microsoft.Agents.AI.Squad` is silent until then. 0.4.0 makes activity emission the default: * New `SquadAgentOptions.EmitSubagentActivities` (defaults to `true`). * `SquadAgent` installs `SquadSubagentTraceMapper` whenever `EmitSubagentActivities || OnSubagentTrace != null`, so spans flow with zero extra wiring. * `OnSubagentTrace` becomes a pure customisation hook (logging, dashboards, metrics) — independent of telemetry. Set `EmitSubagentActivities = false` to opt out of built-in spans when you want to handle telemetry yourself. Plus richer span shape: every lifecycle phase is now an `ActivityEvent` on the live subagent span (visible as annotated markers on the timeline in Aspire / Jaeger / etc.): * `squad.subagent.start` — on SubagentStarted * `squad.subagent.message` — on AssistantMessage (with message_preview tag) * `squad.subagent.completed` — on SubagentCompleted * `squad.subagent.failed` — on SubagentFailed Net effect for a consumer: builder.Services.AddOpenTelemetry() .WithTracing(t => t.AddSource(SquadAgentDiagnostics.ActivitySourceName)); builder.Services.AddSquadAgent(o => o.SquadFolderPath = "/team"); …and the dashboard lights up. No callback wiring, no Activity.Current?.AddEvent plumbing in the host. ## 2. Aspire-style connection-string lookup (with legacy fallback) Aspire injects connection strings under the literal resource name — e.g. an AppHost that calls `builder.AddSquad("research-squad", ...)` exposes `ConnectionStrings:research-squad` to the consumer. The 0.3.0 SDK only looked at `ConnectionStrings:squad-research-squad` (prefixed), so Aspire consumers had to manually call `Configuration.GetConnectionString(name)`, parse the URI, and feed `SquadFolderPath` into the configure callback themselves. 0.4.0 tries the literal name first and falls back to the legacy prefixed form: | Style | Example | Lookup | |--------------------------------------|---------------------------------------------|--------------------------------------------| | Aspire-style direct (tried first) | `AddSquadAgent("research-squad")` | `ConnectionStrings:research-squad` | | Legacy prefixed fallback | `AddSquadAgent("research")` | `ConnectionStrings:squad-research` | Both work. Existing consumers using `ConnectionStrings:squad-{name}` continue unchanged; new Aspire consumers get the natural one-line registration. ## Tests 54 → 64 tests, all passing on net8.0/9.0/10.0. New `SquadAgentDefaultObservabilityTests` covers: * Default-on activity emission (without consumer callback) * Opt-out path (`EmitSubagentActivities = false`) — span suppression + callback still fires * Each ActivityEvent name (`start` / `message` / `completed` / `failed`) * Connection-string precedence: Aspire-direct preferred, prefixed fallback used, same rule applies for keyed registrations Existing `SquadSubagentTraceTests` and the new class share an `[Collection("SquadActivityListeners")]` so they run serially — process-global `ActivityListener` state caused cross-test pollution otherwise. ## Files * `src/Squad.Agents.AI/SquadAgentOptions.cs` — new `EmitSubagentActivities` property + reworked `OnSubagentTrace` XML doc to clarify independence. * `src/Squad.Agents.AI/SquadAgent.cs` — install trace mapper when telemetry OR callback is requested. * `src/Squad.Agents.AI/SquadSubagentTraceMapper.cs` — accept `emitActivities` flag; gate `StartActivity`/`Dispose` on it; add `ActivityEvent` annotations at every lifecycle boundary. * `src/Squad.Agents.AI/SquadAgentOptionsConfigurator.cs` — accept a list of candidate connection-string names; first non-empty wins. * `src/Squad.Agents.AI/SquadServiceCollectionExtensions.cs` — new `GetConnectionStringNames` returns `[name, "squad-"+name]` so both Aspire and legacy conventions resolve. * `src/Squad.Agents.AI/Squad.Agents.AI.csproj` — bump 0.3.0 → 0.4.0. * `src/Squad.Agents.AI/README.md` — new "Subagent observability" section, updated "Aspire / configuration path" section, two new option rows in the Key Options table. ## Backward compatibility Fully backward compatible. The two-arg `SquadSubagentTraceMapper` constructor defaults `emitActivities` to `true`, `EmitSubagentActivities` defaults to `true`, and the legacy `ConnectionStrings:squad-{name}` lookup still resolves. Net change for an existing consumer that had OnSubagentTrace set: nothing (mapper runs in both 0.3.0 and 0.4.0 because OnSubagentTrace is non-null). Net change for a consumer that did NOT set OnSubagentTrace but did AddSource: they now get spans they always asked for. Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…lt) (bradygaster#1275) * Squad.Agents.AI 0.5.0: auto-inject --agent squad (CLI parity by default) The whole point of SquadAgent is to wrap a Squad coordinator team — but the 0.4.x SDK launched the underlying copilot.exe with the CLI's built-in generic agent. The coordinator therefore had no instructions to eager-execute, fan out, or dispatch via the task tool, so it role-played responses inline. Concretely: this SDK call builder.Services.AddSquadAgent(o => o.SquadFolderPath = teamRoot); did NOT behave the same as running copilot --agent squad interactively against the same team root. Consumers had to remember to add `opts.CliArgs.Add(""--agent""); opts.CliArgs.Add(""squad"");` themselves, which is an SDK leak — the class is literally called SquadAgent. 0.5.0 makes --agent squad the SDK default: * New `SquadAgentOptions.AgentFileName` (defaults to `""squad""`). * On client construction, SquadAgent looks for `{teamRoot}/.github/agents/{AgentFileName}.agent.md`. If it exists, `--agent {AgentFileName}` is auto-prepended to the CLI args. * If the file is missing (folder not Squad-initialized), the inject is silently skipped and a Debug log line explains why. The CLI then starts with its default agent, which is what 0.4.x did anyway. * If the consumer already supplied `--agent X` in `CliArgs`, the explicit value wins and we do NOT add a second one. * Set `AgentFileName = null` (or whitespace) to opt out entirely. Net effect: SquadAgent.RunAsync now matches `copilot --agent squad` for any Squad-initialized team root, without the consumer doing anything. ## Tests 64 -> 71 tests, all passing on net8.0/9.0/10.0. New `SquadAgentDefaultAgentFlagTests` (uses a per-test temp dir to scaffold or omit the agent file deterministically): * Default AgentFileName is ""squad"" * Auto-inject when squad.agent.md exists * No inject when the file is missing (graceful degradation) * Explicit --agent in CliArgs wins (no second --agent added) * Custom AgentFileName=""data"" injects --agent data when data.agent.md exists * AgentFileName=null opts out entirely * AgentFileName=whitespace opts out entirely Backward compatibility: existing routing tests use a non-existent `C:\squad-team-root` path, so the file-existence check silently skips the inject — those tests continue to pass with no changes. ## Files * `src/Squad.Agents.AI/SquadAgentOptions.cs` — new `AgentFileName` property with XML doc covering the default, the opt-out, and the not-yet-initialized fallback. * `src/Squad.Agents.AI/SquadAgent.cs` — auto-inject logic in `CreateCopilotClient` (after the `--allow-all` block, before `options.CliArgs` are appended) with file-existence + already-supplied guards and a Debug log when the file is missing. * `src/Squad.Agents.AI/Squad.Agents.AI.csproj` — bump 0.4.0 -> 0.5.0. * `src/Squad.Agents.AI/README.md` — new ""Coordinator agent selection"" section with the precedence table; `AgentFileName` row added to Key Options table. * `+test/Squad.Agents.AI.Tests/SquadAgentDefaultAgentFlagTests.cs` Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * amend: use SessionConfig.Agent instead of --agent CLI args GitHub.Copilot SDK's SessionConfigBase exposes an Agent (string) property that is the first-class equivalent of the Copilot CLI's --agent flag. It discovers and loads .github/agents/{name}.agent.md exactly the same way the CLI does, but without us having to munge CliArgs. Switch the 0.5.0 default-coordinator-agent implementation: - SquadAgent now sets sessionConfig.Agent = options.AgentFileName (default ""squad"") right after constructing the SessionConfig, before ConfigureSession runs. - Drop the --agent CliArgs hack (we no longer need to detect ""did the consumer already pass --agent?"" because ConfigureSession naturally wins over our default). - Tests now assert against sessionConfig.Agent via reflection over the inner DelegatingAIAgent — exactly what consumers using ConfigureSession would see. - README ""Coordinator agent selection"" section reworded to say ""sets SessionConfig.Agent"" instead of ""auto-adds --agent"". 71/71 tests still pass on net8.0/9.0/10.0. The fifth new test (ConfigureSession_CanOverrideAutoSetAgent) explicitly proves the ConfigureSession callback can replace the auto-set value, which is the clean override path now that --agent CliArgs is gone. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ot SessionConfig.Agent) (bradygaster#1277) 0.5.0 (bradygaster#1275) replaced the previous --agent CliArgs approach with sessionConfig.Agent = options.AgentFileName, on the theory that the SDK property was the first-class equivalent of the CLI's --agent flag. It is not. SessionConfig.Agent looks up the name in the SDK's CustomAgents registry (programmatic agent definitions, never populated by SquadAgent), NOT in .github/agents/*.agent.md files on disk. The result was a runtime error on every RunAsync call against a Squad-initialised team: Communication error with Copilot CLI: Request session.create failed with message: Custom agent 'squad' not found Verified at GitHub.Copilot.SDK 1.0.0: * SessionConfigBase.Agent (string) — selects from CustomAgents * SessionConfigBase.CustomAgents (IList<CustomAgentConfig>) — programmatically defined inline agents (Name, Prompt, Tools, Skills, Model, etc.). Empty by default. * The CLI's --agent flag is currently the only path that reads .github/agents/{name}.agent.md on disk. 0.5.1 reverts to the original CliArgs implementation: * SquadAgent now auto-prepends '--agent {AgentFileName}' to combinedCliArgs (back to what 0.5.0 originally proposed before the SessionConfig.Agent detour). * The file-existence check at {teamRoot}/.github/agents/{name}.agent.md still gates the inject so non-Squad-initialized folders degrade gracefully (no --agent passed -> CLI uses default agent). * The 'consumer already supplied --agent in CliArgs' guard is back so the SDK does not add a duplicate. Tests: * New SquadAgentDefaultAgentFlagTests covers all seven cases via reflection over Connection.Args (the CLI-args path the SDK actually uses): default 'squad' value, auto-inject when file exists, no inject when missing, explicit --agent wins, custom AgentFileName works, AgentFileName=null/whitespace opts out. * The older SquadAgentDefaultAgentTests (which targeted SessionConfig.Agent) is removed since that property does NOT do what we wanted. 71/71 tests passing on net8.0/9.0/10.0. Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…adygaster#1291) Closes bradygaster#1290. Adds CLI surface for managing .squad/squad-registry.json, symmetric to squad upstream. Registry entries are discovery-only (visible to squad discover and squad delegate) but do NOT trigger inheritance of the peer squad's skills/decisions/wisdom/routing. Previously users had to hand-edit .squad/squad-registry.json — even the squad discover empty-state hint told them to "create a squad-registry.json" manually. This adds proper commands: squad registry add <name> <path> # validates manifest, refuses duplicate squad registry list # show all registered peers squad registry remove <name> # remove by name Also fixes a subtle path-semantics confusion: readManifest() now accepts BOTH the repo root AND a path with a trailing .squad segment. The docs and SKILL.md showed the .squad-suffixed form but the code previously joined .squad/manifest.json onto whatever you gave it, so the suffixed form silently failed empirical reproduction (discover returned nothing). Test coverage: 18 new tests in cross-squad-registry.test.ts covering the dual-path readManifest fix, registry round-trip, add/list/remove behavior including duplicate-name and invalid-manifest rejection, and end-to-end integration with discoverSquads. Also updates: - cross-squad SKILL.md (canonical + 2 template mirrors) to document the registry vs upstream distinction explicitly - squad discover empty-state hint to mention squad registry add - squad help text with the new commands - SDK exports for the new registry helpers + RegistryEntry/ AddRegistryEntryResult types End-to-end verified locally: - squad registry add (both repo-root and .squad-suffixed paths) - squad registry list (rich output) - squad registry remove (success + missing-name warning) - squad discover picks up registry entries with source=registry - 50/50 tests pass (32 existing + 18 new) - npm run build clean Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…very init/upgrade (bradygaster#1296) (bradygaster#1298) * fix(cli): stop writing squad_state to ~/.copilot/mcp-config.json on every init/upgrade (bradygaster#1296) squad init (init.ts:408) and squad upgrade (upgrade.ts:738) unconditionally called ensureSquadStateMcpInUserConfig, writing squad_state_<hash> to ~/.copilot/mcp-config.json keyed by a stable project-path hash. Each new squad init accumulated another entry in HOME with no garbage collection. This contradicted the explicit iter-8 design intent documented at packages/squad-cli/src/cli/core/mcp-root.ts:1-27, which says iter-8 stops writing to HOME and writes squad_state ONLY to repo-root .mcp.json. The repo-root .mcp.json writes (init.ts:403 / upgrade.ts:728) already cover all documented Copilot CLI launch modes - copilot and copilot -p both walk up from cwd to find .mcp.json. Out-of-tree copilot -p invocations should use --additional-mcp-config @.mcp.json (already documented at init.ts:494). Changes: * Removed the unconditional ensureSquadStateMcpInUserConfig call from init.ts:408 and upgrade.ts:738. Replaced both with comments explaining iter-8 + bradygaster#1296. * Removed the now-unused import from both files. * Kept the function definition at mcp-root.ts:178-228 - a future squad doctor --mcp-prune cleanup helper may want to inspect HOME. Tests: * New regression test in test/cli/init.test.ts: "should NOT write any squad_state entries to ~/.copilot/mcp-config.json (bradygaster#1296)". Isolates the developer's real HOME by setting USERPROFILE/HOME to a temp dir before init, asserts no squad_state* keys appear under temp HOME. * All 40 existing init tests still pass. npm run lint clean. Closes bradygaster#1296 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: comments reference actual Copilot CLI version (≥1.0.59), drop hardcoded test line numbers Reviewer follow-ups on bradygaster#1298 (closes bradygaster#1296): 1. The comments in init.ts/upgrade.ts/mcp-root.ts referenced 'Copilot CLI 5.3+' as the version that auto-loads .mcp.json. The real shipping CLI is at 1.0.62 (5.3 was a typo'd projection from review). Updated all 5 occurrences to '≥1.0.59' — the lowest version where the .mcp.json walk-up behavior is documented. 2. The init.test.ts regression comment hard-coded line numbers (init.ts:408, upgrade.ts:738) that will go stale on any unrelated edit to those files. Rewrote the comment to identify the call by function name (ensureSquadStateMcpInUserConfig) instead — durable against re-orderings. Verified: regression: bradygaster#1296 test still passes (1/16 in init.test). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(init): post-init package.json script tip includes --agent squad The post-init tip showing how to add a non-interactive `squad:copilot` script to package.json was: "squad:copilot": "copilot --additional-mcp-config @.mcp.json" This omits `--agent squad`, so users who copy/paste it get a generic Copilot CLI session that doesn't load the Squad coordinator, team.md, casting, or MCP-wired memory/state tools — only the additional MCP config gets loaded. Same underlying issue surfaced in the cross-squad- communication SKILL.md sweep (squad/wire-cross-squad-skill commit 6b0eac2): anywhere we spawn `copilot` into a Squad-initialised repo, we must pass `--agent squad`. Single-line fix: "squad:copilot": "copilot --agent squad --additional-mcp-config @.mcp.json" Verified: a fresh `squad init` smoke test now prints the corrected tip line verbatim. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…y\ (bradygaster#1288) (bradygaster#1293) * fix(sdk): wire team.md/routing.md/casting state on `squad preset apply` (bradygaster#1288) `squad preset apply <name>` only copied agent charters into .squad/agents/. It left .squad/team.md `## Members` empty, .squad/routing.md missing `## Work Type -> Agent` rows, and never created .squad/casting/registry.json, history.json, or policy.json. Net result: the coordinator's mode-switch check saw an empty Members table and treated every session as Init Mode, proposing to re-scaffold the team the user already applied. This change adds a merge-friendly scaffold module (packages/squad-sdk/src/presets/scaffold.ts) that runs after charters are copied and: * writes/updates team.md `## Members` (creates from scratch if missing; appends new rows to an existing table while preserving the surrounding Coordinator / Project Context sections; idempotent on repeat apply) * writes/updates routing.md `## Work Type -> Agent` (creates or appends) * writes/merges casting/registry.json (universe = `preset:<name>`) * appends a snapshot to casting/history.json + a universe_usage_history entry * creates casting/policy.json with defaults only if missing (never clobbers) Agents with `status: 'error'` are excluded from wiring; agents with `status: 'skipped'` (already exist in target) ARE wired so the team reflects user intent. Scaffolder failure is reported as a synthetic error result without masking the per-agent install results. Verified: * npm run lint passes * test/presets.test.ts: 28/28 pass including 4 new regression tests - wires preset agents into team.md ## Members (bradygaster#1288) - merges preset agents into an existing team.md without duplicating rows - writes casting registry.json, history.json, and policy.json (bradygaster#1288) - appends routing rows for preset agents to routing.md (bradygaster#1288) Out of scope (tracked separately): deduplicating these writers with the equivalent fresh-write versions in packages/squad-cli/src/cli/core/cast.ts. Closes bradygaster#1288 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(presets): role-aware Status cell + non-colliding sentinel for synthetic scaffold error Two reviewer follow-ups on bradygaster#1293 (closes bradygaster#1288): 1. Members-table Status was hardcoded to '✅ Active' for every preset agent. Presets that ship one of the always-on built-ins (Scribe, Ralph, Rai, Fact Checker) would render with the wrong status label compared to a fresh cast: '✅ Active' instead of '📋 Silent' / '🔄 Monitor' / '🛡️ RAI' / '🔍 Verifier'. Added a small statusForRole() helper that mirrors the role→status mapping in cast.ts:652-655 (case-insensitive role matching to tolerate preset authors who lowercase the role string). Built-in role names get their canonical labels; everything else falls back to '✅ Active'. Added a regression test asserting the labels for a preset that ships scribe/ralph/rai/fact-checker + one regular agent. 2. Synthetic scaffold-failure result row used 'agent: presetName' for its 'agent' field. If the preset itself happens to include an agent literally named after the preset ('squad preset apply geektime' on a preset whose roster has a 'geektime' agent), the consumer of PresetApplyResult[] could not distinguish the synthetic scaffold- level error from a real per-agent install error. Replaced with the angle-bracketed sentinel '<scaffold>' (which validateName() rejects, so it can never collide with a real agent name) and moved the preset name into the human-readable reason string so consumers don't lose that context. Verified: 29/29 preset tests pass (28 existing + 1 new role-status test). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…bradygaster#1299) (bradygaster#1300) * fix(docs): tell coordinator to roster Fact Checker on first-time cast (bradygaster#1299) squad init correctly creates .squad/agents/fact-checker/ on disk (per merged PR bradygaster#1223). But when the user opens copilot --agent squad and the coordinator runs first-time casting, it OMITS Fact Checker from the team.md ## Members table while including Scribe, Ralph, and Rai. Root cause: .squad-templates/squad.agent.md had two gaps: 1. Line 56 said "team size (typically 4-5 + Scribe)" — naming only Scribe 2. Rai had a dedicated ## Rai section with explicit "Rai always appears in team.md" instruction — Fact Checker had no equivalent section So the model added Rai (because instructed to) but had no instruction to add Fact Checker, even though the agent dir was scaffolded on disk. Fix: * Update team-size line to name all 4 always-on built-ins: Scribe + Ralph + Rai + Fact Checker * Add full ## Fact Checker — Verification & Devil's Advocate section mirroring the Rai pattern: roster-entry instruction, dual operating mode (per bradygaster#789 + bradygaster#1254), trigger phrase table, confidence ratings, DA brief structure, boundaries, state location Sync via sync-templates.mjs --sync propagates squad.agent.md changes to all 4 mirror targets: .squad-templates/, templates/, packages/squad-cli/ templates/, packages/squad-sdk/templates/, .github/agents/. Tests: new test/squad-agent-roster.test.ts runs against all 4 template targets and asserts: * The "Determine team size" line names all 4 built-ins * A ## Fact Checker section exists with "always appears in team.md" * The section declares dual operating mode (anchors bradygaster#789 + bradygaster#1254 design so a future PR can't accidentally split Fact Checker and Devil's Advocate again — cf. closed PR bradygaster#1294) * Existing Ralph + Rai sections still present 16/16 pass. Closes bradygaster#1299 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * doc(squad.agent.md): clarify Fact Checker is exempt from casting + correct on-demand reference path Reviewer follow-ups on bradygaster#1300: 1. Team-size phrasing — the line read 'typically 4-5 + Scribe + Ralph + Rai + Fact Checker' which a model could parse as arithmetic (4-5 + 4 = 8-9, but it could also collapse). Rewrote it to make the composition explicit: '4-5 cast (user-domain) agents + 4 always-on built-ins = 8-9 total roster entries'. 2. Cast-exemption parity — Scribe, Ralph, and Rai each have an explicit 'exempt from casting' bullet but Fact Checker did not. Added the matching bullet right after Rai's. 3. Bad on-demand reference path — the FC section pointed at '.squad/templates/fact-checker-charter.md'. That file IS shipped (TEMPLATE_MANIFEST destination 'templates/fact-checker-charter.md') but only AFTER 'squad init' or 'squad upgrade' has populated .squad/templates/. A reader of squad.agent.md on an un-initialized repo (or in .github/agents/ on the cloud agent surface) would follow a dead link. Repointed to the '.squad/agents/fact-checker/charter.md' instance that ensureBuiltinAgents creates as part of the same init/upgrade path — that's where the rich charter actually lives at runtime per bradygaster#1299 + bradygaster#1301. All 4 mirrored copies re-synced via scripts/sync-templates.mjs. fact-checker-role.test.ts: 8/8 pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…/fact-checker/ state dir (bradygaster#1299 deep) (bradygaster#1301) * fix(sdk): plumb Fact Checker like Rai — rich charter at init + .squad/fact-checker/ state dir (bradygaster#1299 deep) PR bradygaster#1300 fixed the documentation gap so the coordinator knows to roster Fact Checker. This PR fixes the structural gap behind it. Per user testing 2026-06-13: even after bradygaster#1300 the actual agent on disk was still "a name on disk with a 21-line placeholder". Three structural problems: 1. squad init never used the rich {role}-charter.md templates. Both Rai and fact-checker got 478-byte generic stubs from generateCharter(). Rich templates only ran via squad upgrade's ensureBuiltinAgents path. 2. fact-checker had no state dir. Rai gets .squad/rai/{policy.md, audit-trail.md} via init.ts lines 879-941. fact-checker had nothing equivalent. 3. fact-checker-charter.md was only in packages/squad-cli/templates/ — missing from .squad-templates/ (canonical source) AND packages/ squad-sdk/templates/. SDK init's getSDKTemplatesDir() resolves to the SDK templates dir, so even if init tried to read the rich charter, the file wasn't there. Fix (4 parts): Part 1 - Rich charter at init (benefits BOTH Rai and fact-checker): * SDK init.ts agent loop now looks up {templatesDir}/{role}-charter.md for each agent and uses that as charter.md content if it exists. Falls back to generateCharter() for user-defined agents. * Result: fresh squad init produces .squad/agents/Rai/charter.md at 4525 bytes (full Rai charter) and fact-checker/charter.md at 3024 bytes (full FC charter). Previously both were 478-byte stubs. Part 2 - .squad/fact-checker/ state dir mirroring .squad/rai/: * New block in init.ts (right after the Rai seeding) creates .squad/fact-checker/policy.md (from templates/fact-checker-policy.md or inline fallback) and audit-trail.md. * New .squad-templates/fact-checker-policy.md (~6KB) is the canonical authority for dual-mode operating rules per bradygaster#789 + bradygaster#1254: - Mode 1 Verification: ✅/⚠️ /❌/🔍 confidence rating taxonomy - Mode 2 Devil's Advocate: required brief structure - Hard anti-fabrication rules - Advisory by default with narrow blocking exceptions - Audit trail rules (succinct, never raw source) Part 3 - Fix .squad-templates/ distribution gap: * Copied fact-checker-charter.md into .squad-templates/ so sync-templates.mjs propagates it to all 4 mirror targets including packages/squad-sdk/templates/. This unblocks Part 1. Part 4 - Plumbing: * .gitattributes: .squad/fact-checker/audit-trail.md merge=union * TEMPLATE_MANIFEST: fact-checker-policy.md * squad.agent.md Files Catalog: 2 new rows for FC state files Tests: 3 new regression tests in test/init.test.ts (28/28 pass total). npm run lint clean. Composability: This PR builds on bradygaster#1300 (which adds the ## Fact Checker section to squad.agent.md and the team-size line fix). Both PRs modify squad.agent.md in disjoint regions and merge in either order. Full plumbing requires BOTH to land. Closes bradygaster#1299 (deep fix; bradygaster#1300 was the surface fix) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(sdk): lowercase fallback for rich-charter template lookup + sync .github/agents Two reviewer follow-ups on bradygaster#1301 (bradygaster#1299 deep): 1. Case-sensitive FS bug in rich-charter lookup The lookup tried '\-charter.md' and '\-charter.md' only. For Rai (role='Rai', name='Rai') this becomes 'Rai-charter.md', but the actual file shipped lowercase ('rai-charter.md'). On Windows the lookup succeeded because the filesystem is case-insensitive; on Linux CI it silently missed and fell back to the 478-byte generic stub — exactly the regression bradygaster#1299 was trying to fix. Reproduced by 'should use the rich Rai-charter.md template at init' failing with 'expected 476 to be greater than 1000' on GitHub Actions. Add toLowerCase() candidates after the exact-case ones. De-dupe via a Set so we don't double-stat when role and name are already lowercase (fact-checker case). Guard each candidate against blank keys. 2. Template-sync parity The canonical .squad-templates/squad.agent.md gained two Fact Checker rows in the Files Catalog but the mirrored .github/agents/squad.agent.md copy was never re-synced, so the template-sync.test.ts byte-for-byte parity check would have fired. Run 'node scripts/sync-templates.mjs --sync' to regenerate. Verified: vitest 'rich Rai-charter' passes locally after the fix (previously failing on Linux CI run 27464079078). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…des bradygaster#1297) (bradygaster#1302) * fix(skills): rename disambiguation skill 'squad' -> 'squad-help' (supersedes bradygaster#1297) PR bradygaster#1297 added a disambiguation skill named 'squad' so models calling skill(Squad) would get a redirect. After local end-to-end testing on 2026-06-13: skill ships to disk correctly but never shows up in Copilot CLI's /skills list. Root cause (verified against Copilot CLI source 1.0.62-2 app.js): 1. Copilot CLI's skill schema is {name, description, source, baseDir, allowedTools, pluginName, pluginVersion} (line 989). Frontmatter fields triggers:, domain:, confidence:, license: are silently ignored. 2. Skill loader returns {skills, warnings, errors} (line 4427). Skills that fail to load are reported as errors. 3. A skill named 'squad' collides with the Copilot agent named 'Squad' (registered at .github/agents/squad.agent.md). The agent wins; the skill is hidden from /skills. Fix: * Rename 'squad' -> 'squad-help' (avoids the agent-name collision; still descriptive enough for natural-language match when user says 'how do I use squad' or 'squad help') * SKILL.md content: name: 'squad-help', removed unused triggers:/domain:/ confidence:/source:/license: fields, added allowedTools: [], rewrote description: to be self-explanatory, added explicit note that /squad slash command does NOT exist (slash commands are CLI built-ins, not auto-mapped from skills) * MANIFEST_SKILL_NAMES in sdk-init.ts: 'squad' -> 'squad-help' * New TEMPLATE_MANIFEST entry in templates.ts for squad-help (so squad upgrade also propagates the skill - that code path uses TEMPLATE_MANIFEST instead of MANIFEST_SKILL_NAMES) Tests: new test asserts .copilot/skills/squad-help/SKILL.md exists with right frontmatter; explicit regression guard against re-introducing name: 'squad'. 26/26 init tests pass. npm run lint clean. Supersedes bradygaster#1297. Out of scope (separate issue worth filing): squad upgrade synced only 10 of 16 installed skills - TEMPLATE_MANIFEST (used by upgrade) is out of sync with MANIFEST_SKILL_NAMES (used by init). Skills from PRs bradygaster#1292 + bradygaster#1295 (tiered-memory, iterative-retrieval, reflect, cross-squad, cross-squad-communication) have entries in MANIFEST_SKILL_NAMES but not TEMPLATE_MANIFEST. Follow-up will fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(skill): add confidence + domain frontmatter to squad-help Reviewer follow-up on bradygaster#1302: the isSkillContent() classifier in sharing/consult.ts:990 requires BOTH name: AND confidence: in the frontmatter to recognize a file as a skill. Without confidence:, squad-help would not be detected as a skill in cross-squad merge / share / promote flows — it would be misclassified as a generic markdown decision. The Copilot CLI itself silently ignores custom frontmatter fields (per sdk/index.js decompile — only name/description/allowedTools/ user-invocable are read), so adding confidence: high and domain: squad-onboarding is safe at the CLI surface and necessary at the SDK surface. Applied identically to all 3 mirrored copies of squad-help/SKILL.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…re mutating state (closes bradygaster#1305) (bradygaster#1306) * fix(prompt): coordinator must probe for squad_state/memory tools before mutating state on non-local backends (closes bradygaster#1305) Symptom: a coordinator session against a Squad with stateBackend two-layer wrote .squad/decisions.md and history files via raw create/edit tools, never calling any squad_state or memory tool. The pre-commit hook caught the contract violation; the agent treated it as a 'git problem' instead of the symptom it was. Root cause: two failure modes stacked. Mechanical (Copilot CLI): MCP server tools are loaded lazily, not always advertised in the model's initial function list. Squad cannot fix this server-side; out of scope. Behavioral (squad.agent.md): pre-1305 prompt said 'when memory tools are available, use them' which models read as 'if listed' instead of 'after probing'. No hard refusal clause when the agent is about to violate the state-backend contract. Two changes to .squad-templates/squad.agent.md (synced to 4 mirror targets): 1. New 'State-backend handshake' section (MANDATORY, every session): - Skip for local/worktree backends - For orphan/two-layer/git-notes: probe via tool_search_tool_regex for squad_state_health; call it to confirm the bridge answers - On probe fail: HALT and tell the user verbatim how to fix (restart Copilot CLI or change stateBackend to local) 2. Replaced soft 'if not available' language with a HARD RULE in Memory Governance Tools section. Lists 10 forbidden paths (decisions.md, decisions/inbox, agents history, casting JSON, identity, memory, orchestration-log, log, rai+fact-checker audit-trail) that MUST NOT be written via create/edit/write_file on non-local backends when the bridge isn't reachable. Preserved the local/worktree carve-out. Also clarified that memory.* and squad_state_* share the same MCP server (same registry in packages/squad-cli/src/cli/commands/state- mcp.ts), so models stop treating them as separate availability checks. Tests: new test/state-backend-handshake.test.ts asserts 5 invariants against all 4 template mirror targets (20 tests total): handshake mandatory + every-session timing + squad_state_health probe + HALT remediation + HARD RULE with forbidden paths + local-backend carve- out. 20/20 pass. npm run lint clean. Out of scope: server-side MCP tool preload (Copilot CLI feature request), skill reinforcement in init-mode/agent-conduct (small follow-up). Closes bradygaster#1305 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: tighten handshake-rule regex (split into 3 separate assertions) Reviewer follow-up on bradygaster#1306: the regex '/create.*edit.*write_file|create\s*\/\s*edit/i' has '|' operator precedence ambiguity — the alternation binds at the top, so the shorter branch 'create\s*/\s*edit' could match the rule paragraph even if 'write_file' was missing entirely. The test was meant to ensure all three tool names appear in the HARD RULE list; this fix replaces it with three separate \b-anchored assertions, one per tool, so dropping any one fails the test. 20/20 handshake tests still pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…+ rename squad-commands → squad) (bradygaster#1303) * feat(skills): make /squad a real slash command — rename squad-commands to squad with user-invocable:true Users want /squad in Copilot CLI to show Squad's command catalog. Verified via Copilot CLI 1.0.62-2 source (sdk/index.js line 2618): getLoadedSkills().filter(e => e.userInvocable) .map(e => ({name: \/\\, isSkill: true, skill: e})) Any skill with frontmatter user-invocable: true is auto-registered as a slash command at /<skill-name>. The previous skill 'squad-commands' had no user-invocable field (Copilot CLI defaults to false), so /squad-commands never existed and users had no slash entrypoint. Changes: * Renamed squad-commands -> squad (canonical .squad/skills/squad/) * Frontmatter rewritten to Copilot CLI schema: - name: squad (was squad-commands) - user-invocable: true (the load-bearing change) - description: self-explanatory for natural-language match - allowedTools: [] - Removed unused fields: domain:, confidence:, source:, triggers: * Body updated to reference /squad as primary invocation * MANIFEST_SKILL_NAMES updated * TEMPLATE_MANIFEST updated (so squad upgrade syncs it too) * Removed stale squad-commands template dirs from both packages Tests: new test asserts user-invocable: true frontmatter AND name: squad (both are load-bearing for the slash command to register). 26/26 init tests pass. npm run lint clean. Composability: * Disjoint from bradygaster#1292 (skills bundling) - both touch MANIFEST_SKILL_NAMES but this is a rename not an add * Disjoint from bradygaster#1302 (squad-help disambiguation) - that one covers the skill(Squad) misdirect, this one covers the /squad slash UX Out of scope (future): machine-wide install (~/.copilot/skills/squad/) so /squad init works in folders without .squad/ yet. Requires a squad install --global-skill command + 'no .squad yet' menu branch. Will file separate follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(squad.agent.md): update squad-commands → squad skill xref Follow-up to reviewer comment on bradygaster#1303: when this PR renamed '.copilot/skills/squad-commands/SKILL.md' to '.copilot/skills/squad/SKILL.md' (to make /squad a real user-invocable slash command), the routing-table entry inside squad.agent.md still pointed at the old path. Coordinators loading squad.agent.md from a freshly upgraded squad would have followed a dead reference and reported 'skill not found'. Updated the row in all 5 mirrored copies (.squad-templates, .github/agents, packages/squad-cli/templates, packages/squad-sdk/templates, templates/). Also added a hint that users can invoke the skill directly via /squad, since that is now the documented surface for the same content. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…aster#1126) (bradygaster#1304) * fix(skills): install bundled skills to .github/skills/ (closes bradygaster#1126) Per the official Agent Skills spec docs (GitHub, VS Code), the canonical project-level custom-skills location is .github/skills/. The legacy .copilot/skills/ is invisible to all Copilot surfaces except Squad itself - cloud agent, CLI outside Squad, VS Code extension, @copilot coding agent all ignore it. Changes: * squad init writes bundled skills to .github/skills/{name}/SKILL.md * squad upgrade does the same AND migrates legacy .copilot/skills/{name}/ -> .github/skills/{name}/ for manifest skills only (user-added skills at .copilot/skills/ are preserved). Tombstones empty legacy dir. * TEMPLATE_MANIFEST destinations: 10 skill entries retargeted * ENSURE_DIRECTORIES: .copilot/skills -> .github/skills * squad.agent.md narrative: 5-path scan order now lists .github/skills as primary, .copilot/skills as legacy. Personal scope unchanged. * All user-facing docs updated (README, spawn-reference, squad-commands skill, release-process skill, build.ts skill creation paths, SDK type-comment paths). Migration semantics in upgrade.ts: * Move-only-if-new-location-empty: legacy at .copilot/skills/, new location empty -> move + tombstone legacy * Tombstone-on-collision: both locations exist -> remove legacy, new wins (then syncAllSkills overwrites manifest skills per overwriteOnUpgrade=true semantics) * Preserve user-added: skills NOT in TEMPLATE_MANIFEST stay at .copilot/skills/ untouched * All best-effort with try/catch - disk failures do not block upgrade Tests (188/188 pass): * New: init.test.ts asserts canonical path + legacy NOT created * New: upgrade.test.ts asserts manifest migration + user-skill preservation + collision tombstoning * Updated: 8 existing test files retargeted to .github/skills NOT changed (intentional): * .copilot/skills/ stays in coordinator skill-discovery scan order for backward compat with user-added skills * ~/.copilot/skills/ (personal scope) unchanged - that's Copilot CLI's official personal-skills location * Runtime skill-loader tests (skill-source, skills-export-import, tools, skill-script-loader) unchanged - those test loader behavior which still supports .copilot/skills/ as a scan path Closes bradygaster#1126 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: squad_skill writes to .github/skills, sync .github/agents copy, align issue refs Reviewer follow-ups on bradygaster#1304 (closes bradygaster#1126): 1. squad_skill tool implementation matches its description now Description says skills live at '.github/skills/{name}/SKILL.md' but the handler was still writing to '.copilot/skills/' — every successful 'write' shipped to a different path than what the tool documented (and what squad init/upgrade now install to). Fixed the handler so: - write operations go to '.github/skills/{name}/SKILL.md' - read operations check .github/skills first, then fall back to .copilot/skills (legacy) and .squad/skills (in-repo team skills), in that precedence — so users with un-migrated existing skills can still read them. 2. .github/agents/squad.agent.md re-synced from .squad-templates The canonical template had the corrected routing-table reference ('.github/skills/squad-commands/SKILL.md') but the .github/agents mirror copy was never re-synced. The byte-for-byte template-sync parity test would have fired on next CI. Ran 'node scripts/sync-templates.mjs --sync'. 3. Align issue references: bradygaster#1304 → bradygaster#1126 in code/docs/tests This PR closes bradygaster#1126; bradygaster#1304 is the PR number. The migrator docstring, the init.ts comment, and the two upgrade.test.ts cases all called the regression 'bradygaster#1304' — confusing for anyone digging into git blame for the canonical issue. Renamed to bradygaster#1126 where the references describe the bug origin (kept bradygaster#1304 only where the comment specifically describes 'the PR that implemented it'). 4. Migrator docstring corrected to match reality Old docstring claimed 'skips skills already present at the new location with the same content' but the implementation never compares content — it unconditionally tombstones the legacy copy when the new location exists. Rewrote the doc paragraph to describe what the code actually does (preserves the new-location copy verbatim). Verified locally: ✓ vitest test/cli/upgrade.test.ts -t 'migrate manifest skills|should NOT clobber' ✓ vitest test/tools.test.ts -t squad_skill Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(tools): squad_skill writes go to .github/skills now (CI fix) CI failure on commit 9de50de: 'squad_skill handler > should write skill file' and 'should default confidence to medium' both still asserted '.copilot/skills/{name}/SKILL.md' as the write destination. With squad_skill's handler now writing to '.github/skills/' (the canonical Copilot CLI custom-skills location, per the fix in the same commit), those assertions need to be updated. The handler's read-fallback chain still finds .copilot/skills/ and .squad/skills/ for legacy installs, but the write target is fixed. Verified locally: 5/5 squad_skill tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test(init): update squad-help + /squad slash test paths to .github/skills/ (cascade fix on top of bradygaster#1126) After bradygaster#1303 + bradygaster#1302 landed first (with their tests asserting .copilot/skills/), the rebase of bradygaster#1304 (which moves manifest skills to .github/skills/) leaves the test paths pointing at the old location. Update them so the rebased branch's CI is green. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…s-squad protocols) (bradygaster#1295) * feat(sdk): bundle cross-squad-communication skill (bradygaster#5 cross-squad protocols) PR bradygaster#1291 added squad registry add/list/remove and the cross-squad/SKILL.md for peer discovery. But discovery is only half the story — once a peer is known, agents need to know HOW to actually exchange info with it. This change ports cross-squad-communication from tamirdresher/squad-skills into the bundled skills so a fresh squad init produces a coordinator that knows the four communication patterns: * Pattern 0: Synchronous CLI session (--working-directory targeting peer) * Pattern 1: Read-only metadata scan (team.md / decisions.md) * Pattern 2: Async git-based request/response (.squad/cross-squad/...) * Pattern 3: Issue-based delegation (gh issue with squad:cross-squad label) Plus decision tree for pattern choice, anti-patterns, request/response YAML schemas, and validation status. Changes: * .squad/skills/cross-squad-communication/SKILL.md (379 lines, canonical source). sync-skill-templates.mjs propagates to both packages templates. * MANIFEST_SKILL_NAMES in packages/squad-sdk/src/config/init.ts grows by 1 entry: cross-squad-communication. Now 11 entries. * cross-squad/SKILL.md gets a one-paragraph "Companion skill" note pointing to cross-squad-communication for protocol details. Together: cross-squad answers "who?" (registry discovery), cross-squad-communication answers "how?" (the 4 patterns). The original plugin documented validation against specific internal Microsoft repos. Examples in this version use generic names (platform-squad, research-squad) so they are meaningful to upstream users. Protocol mechanics are unchanged. Frontmatter source: attributes the port. Test: new "should install cross-squad-communication skill" in init.test.ts asserts SKILL.md is at install path and content contains expected pattern names. 26/26 init tests pass. npm run lint clean. Composes with bradygaster#1291: * squad init → both skills bundled * squad registry add ../peer → peer discoverable * coordinator: "ask peer X for their team members" → uses Pattern 1 by reading team.md from the registered peer Note on overlap with bradygaster#1292: PR bradygaster#1292 (skills bundling fix) adds 4 entries to MANIFEST_SKILL_NAMES; this PR adds 1. Disjoint additions to the same array; either can land first. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: TEMPLATE_MANIFEST entry for cross-squad-communication + pattern numbering + honest source/validation Five reviewer follow-ups on bradygaster#1295: 1. MANIFEST_SKILL_NAMES added 'cross-squad-communication' but TEMPLATE_MANIFEST didn't — 'squad upgrade' would skip the skill even though 'squad init' installed it. Added the missing entry to TEMPLATE_MANIFEST so upgrade syncs it like every other manifest skill. (Same drift bug pattern noted on bradygaster#1292/bradygaster#1303.) 2-3. Both SKILL.md files (companion 'cross-squad' and full 'cross-squad-communication') said the skill covers 'the four communication patterns (sync CLI, async git-based, issue-based)' but only listed three — Pattern 1 (read-only knowledge query) was missing from the intro list. Rewrote both intro lines to spell out all four: Pattern 0 (sync CLI), Pattern 1 (read-only), Pattern 2 (git-based async), Pattern 3 (issue-based). 4. The doc had 'Pattern 4: Cross-Repo Dependency Scan' which broke the 'four numbered patterns 0-3' framing — Pattern 4 isn't a communication protocol, it's a one-off analysis utility for discovering how two repos relate. Moved it to a clearly labeled '### Appendix' section with a note explaining why it's not a numbered pattern. 5. Frontmatter 'source:' claimed the skill was 'validated against two production squad instances' but the Validation Status section said Patterns 2 and 3 were 'untested end-to-end'. Reworded 'source:' to acknowledge that only Pattern 0 (and partially Pattern 1) are end-to-end-validated; Patterns 2/3 are documented from design and need live validation before production use. Also softened the same overclaim in the Validation Status prose (replaced 'validated against two production' with 'drafted against two prototype' + explicit acknowledgement that 2/3 are design-only). All 3 mirrored copies of cross-squad-communication/SKILL.md and 3 copies of cross-squad/SKILL.md kept in sync (canonical = .squad/, mirrors = packages/squad-cli/templates/, packages/squad-sdk/templates/). Verified: 31/31 init + builtin-skills tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(skill): cross-squad-communication uses real Copilot CLI invocations (ghcs→copilot, real flags) The cross-squad-communication SKILL.md as drafted instructed coordinators to use a non-existent CLI shape. Verified empirically against `copilot --help` (v1.0.62): - `ghcs` is not a binary on a clean install; the real CLI is `copilot` (resolved to C:\ProgramData\global-npm\copilot.ps1 on a default node install). - `--working-directory <dir>` does not exist. Real flag is `-C <directory>` (git-style "change directory first"). - `--no-mcp` does not exist. Real flag is `--disable-builtin-mcps`. - `-p, --prompt <text>` takes the prompt STRING, not a path. Earlier examples passed `-p \` (a path), which makes the CLI try to execute the path string as a prompt. Read the file with `Get-Content -Raw` first. - `--allow-all-tools` was missing from autonomous (non-interactive) invocations — without it every tool call prompts for permission and hangs the cross-squad delegation indefinitely. - Log directory was `~/.agency/logs/` (older `agency` runtime). New CLI logs under `~/.copilot/logs/`. Switched to a `Test-Path`-guarded fallback so both transitional and clean installs resolve correctly. All 14 call-site occurrences in cross-squad-communication/SKILL.md updated (3 mirrored copies). Mirrors verified byte-identical. New regression test in test/cross-squad.test.ts asserts each of the 8 correctness properties (ghcs/—working-directory/—no-mcp absent; `copilot -C`, `--allow-all-tools`, `--disable-builtin-mcps`, `-p (Get-Content`, and `.copilot\\logs + Test-Path` present) for every mirror. 8 × 3 mirrors = 24 new assertions; 56/56 cross-squad tests pass. Catches a fairly large embarrassment: had this skill landed as drafted, every fresh `squad init` coordinator would have run a totally bogus CLI command on the first delegation attempt. Credit to the peer-squad `read this skill, ran into errors, asked why` loop for surfacing it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(skill): every cross-squad copilot spawn passes --agent squad A peer-squad delegation that runs the Copilot CLI without --agent squad gets a generic Copilot CLI session — the spawned process never loads .github/agents/squad.agent.md, the peer's team.md, MCP tools, casting, or coordinator behaviour. The whole point of cross-squad delegation collapses: the answer comes from an off-the-shelf model, not from the peer's Squad. All 7 example command lines in cross-squad-communication/SKILL.md (Pattern 0 Options A/B/C, Liveness Protocol MCP-skip retry, and the two Anti-Pattern examples) now include --agent squad. Also added a new top-of-Patterns "Universal rule: every copilot spawn into a peer squad MUST pass --agent squad" section that: - States the rule once, prominently. - Explains the failure mode (generic session, no team.md / MCP / coordinator loaded) so future edits don't strip the flag thinking it's redundant. - Notes the only exception (--resume preserves original session agent). - Generalises the rule beyond cross-squad: "anywhere else you spawn copilot into a Squad-initialised repo — e.g., post-init tips and any automation that invokes the CLI on a squadified folder." Also added a precondition note to Pattern 0 Requirements: the target repo must be Squad-initialised (.squad/config.json + .github/agents/squad.agent.md present) so --agent squad resolves. Verified empirically: copilot --help (v1.0.62) confirms --agent <agent> is the real flag name. squad delegate (CLI command) was audited and does NOT need this fix — it uses `gh issue create`, not `copilot`, so the issue body lands in the peer repo's GitHub Issues for async pickup, not via direct CLI spawn. Regression tests in test/cross-squad.test.ts: - 'every copilot spawn into a peer squad includes --agent squad' — scans every copilot command line (excluding --resume / prose references) and asserts each one has --agent squad. Tells you the exact offending line on failure. - 'explains WHY --agent squad is required (universal rule paragraph)' — defends against a future edit that strips the rationale. - 2 new assertions × 3 mirror locations = 6 new tests. - 62/62 cross-squad tests pass. All 3 mirrored copies of cross-squad-communication/SKILL.md kept in sync (canonical = .squad/, mirrors = packages/squad-cli/templates/, packages/squad-sdk/templates/). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…ough the cross-squad skill (bradygaster#1307) * fix(coordinator): route "spawn a squad" / "another squad" prompts through the cross-squad skill A coordinator initialised by `squad init` saw prompts like "spawn two squads of designers and devs" and fanned out raw `task` agents inside its own context, treating "squad" as generic English for "team / group". It never invoked the bundled `cross-squad` or `cross-squad-communication` skills, so the peer-squad delegation protocol (registry / manifest / sync CLI / git-async / GH-issue patterns) was bypassed entirely. Two structural holes in squad.agent.md allowed this: 1. The Routing table had no row mapping "spawn a squad" phrasing to the Squad-PRODUCT concept (only "upgrade squad" / "squad commands" rows covered Squad-as-a-product vocabulary). 2. The Skill-aware-routing block was process discipline ("check skill directories by domain relevance") with no hard "if the user's word matches a skill name, MUST load the skill" trigger. This fix: - Adds a new routing-table row for the squad-spawning vocabulary ("spawn a squad", "another squad", "two squads", "second squad", "fan out to squads", "delegate to a squad"). Action: invoke the skill tool on cross-squad AND cross-squad-communication BEFORE any task spawn, then delegate via Pattern 0/1/2/3. - Adds a "Hard trigger — keyword-to-skill match" paragraph at the top of the Skill-aware-routing block. If any word in the user's request matches an installed skill name (squad → cross-squad, reflect → reflect, ceremony → matching ceremony skill, fact-check → fact-checking, release → release-process), the coordinator MUST invoke the skill tool to fully load that skill before designing its approach. Includes a "failure mode this rule closes" pointer so the guard survives future paraphrasing. - Strengthens cross-squad/SKILL.md with a Read-this-FIRST callout above the existing Context paragraph, so even a coordinator that skips the routing-table row still hits the trigger when it does eventually load the skill. - Adds a regression test (template-sync.test.ts) that asserts the row + the hard-trigger paragraph + the worked example are present in every mirrored copy of squad.agent.md (5 locations). All 4 mirrors re-synced via `scripts/sync-templates.mjs --sync`. Verified: 223/223 template-sync tests pass. Composability: disjoint from bradygaster#1292/bradygaster#1293/bradygaster#1295/bradygaster#1298/bradygaster#1300/bradygaster#1301/bradygaster#1302/ bradygaster#1303/bradygaster#1304/bradygaster#1306 — only touches squad.agent.md mirrors + cross-squad/ SKILL.md + the template-sync test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(coordinator): strengthen squad-spawn disambiguation — ask_user on ambiguity + anti-patterns Real-world failure (2026-06-13): even AFTER the routing-table row and hard-trigger paragraph from b5d05fb landed, a peer-squad coordinator *still* did ad-hoc `task` fan-out for "spawn two squads of engineers and QAs". Self-diagnosis surfaced four contributing failure modes: 1. Prior-session anchoring (saw earlier `reviews/squad-alpha/` folders and matched the pattern without re-evaluating user intent). 2. Ambiguous wording, lazy interpretation (silently picked the cheaper option instead of asking). 3. Coordinator doctrine biases toward `task` fan-out (the existing Eager Execution / Parallel Fan-Out section pulled the coordinator back even after it had loaded `cross-squad`). 4. Cost/overhead instinct ("two real squads for a 30-line app feels disproportionate" — judged silently instead of surfacing the trade-off). The original PR bradygaster#1307 fix closed modes 1 and 3 mechanically (forces the skill to load) but left modes 2 and 4 open (didn't dictate what to DO with that knowledge). This commit closes them: A. squad.agent.md routing row — added two explicit clauses: - "**Default = literal Squad install.** Calling `task` sub-agents 'squad-alpha' / 'squad-beta' does NOT make them squads — that is the explicit anti-pattern." - "**If the request is ambiguous** ... you MUST `ask_user` with a 2-choice prompt — and never silently pick the cheaper option." No escape hatch. The coordinator can no longer rationalise the downgrade as a judgment call. B. cross-squad/SKILL.md — added a full `## Disambiguation: 'squad' vs ad-hoc agents` section with: - Default-behaviour table mapping common phrasings to expected coordinator actions (real squads vs ad-hoc agents vs ambiguous). - ask_user 2-choice protocol verbatim (heavier/persistent vs lighter/ephemeral) so the coordinator has the exact prompt shape. - Four named anti-patterns drawn directly from the observed failure: * Naming task agents "squad-alpha" doesn't make them squads * Prior-session anchoring (pattern is a hint, not a contract) * Silent cheaper-option pick (judgment call belongs to the user) * Loading the skill but doing task fan-out anyway (disambiguation rule OVERRIDES generic fan-out doctrine when "squad" was the trigger) - Sharpened `description:` so the squad skill-aware-router has better natural-language hooks. - `triggers:` frontmatter array (Copilot CLI ignores `triggers:` per sdk/index.js decompile, but the squad coordinator's skill-aware routing system uses natural-language matching against frontmatter + content, so documenting the phrases here helps that matcher fire). C. Regression tests in test/template-sync.test.ts: - Routing row must mention `ask_user` + "anti-pattern" (new × 5 mirrors = 5 assertions). - cross-squad/SKILL.md must have `## Disambiguation` section, default-behaviour rule, ask_user requirement, the squad-alpha anti-pattern, and triggers: frontmatter (5 new × 3 mirrors = 15 assertions). - 20 new assertions total; 243/243 template-sync tests pass. cross-squad/SKILL.md mirrored to packages/squad-cli/templates/skills/ and packages/squad-sdk/templates/skills/ (byte-identical). squad.agent.md re-synced to all 4 mirrors via scripts/sync-templates.mjs. Composability: still disjoint from all other open PRs. Pure additions to two files (squad.agent.md row, cross-squad/SKILL.md content) plus mirrors + tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…-memory provenance (bradygaster#1289, bradygaster#1264) (bradygaster#1292) * fix(sdk,cli): bundle missing skills on init + strip fabricated provenance from tiered-memory (bradygaster#1289, bradygaster#1264) Two regressions shipped in v0.10.0 caused several skills to silently never reach users: * bradygaster#1289 — squad-commands + squad-version-check were in MANIFEST_SKILL_NAMES but missing from packages/squad-sdk/templates/skills/. The install loop silently skipped missing source dirs (storage.existsSync check, no log), so every squad init produced an install with these two absent and the `squad commands` trigger phrase was a dead no-op for every v0.10.0 user. * bradygaster#1264 — tiered-memory, iterative-retrieval, reflect existed in templates but were never added to MANIFEST_SKILL_NAMES. tiered-memory/SKILL.md also claimed confidence: high with fabricated tamirdresher/tamresearch1 measurement data, and referenced a non-existent docs/tiered-memory-guide.md. * PR bradygaster#1291 updated cross-squad/SKILL.md but never added it to the manifest. This change: * Adds 5 missing skill dirs to .squad/skills/ (canonical source): squad-commands, squad-version-check, tiered-memory, iterative-retrieval, reflect. sync-skill-templates.mjs (which runs in prebuild) propagates them to both packages/squad-cli/templates/skills/ and packages/squad-sdk/templates/skills/. * Grows MANIFEST_SKILL_NAMES from 10 → 14 entries: adds tiered-memory, iterative-retrieval, reflect, cross-squad. * Replaces the silent skip in sdk-init.ts with a thrown error that names the missing skill(s) and points at sync-skill-templates.mjs. This is what would have surfaced bradygaster#1289 at build time instead of in user installs. * Rewrites tiered-memory/SKILL.md to be honest about status: - frontmatter: confidence: design + source: design proposal - prominent Status callout linking to bradygaster#1264 for the runtime gap - removed fabricated measurement table - removed reference to non-existent docs/tiered-memory-guide.md - References section points only to real issues (bradygaster#1264, bradygaster#686, bradygaster#600) * Adds a regression test in test/init.test.ts that asserts every manifest-curated skill ends up installed at .copilot/skills/{name}/SKILL.md. Verified: * npm run lint — passes (after build) * test/init.test.ts — 26/26 pass including new regression test * Targeted suites (test/init, test/cli/init, test/sdk) — 292/292 pass Out of scope (tracked separately): * tiered-memory runtime backing (.squad/memory/hot|cold|wiki/ scaffolding, Scribe promotion, tier-aware spawn template) — follow-up in bradygaster#1264 * cross-squad-communication plugin port from tamirdresher/squad-skills — separate PR Closes bradygaster#1289 Refs bradygaster#1264 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: precheck drift, end-user remediation, TEMPLATE_MANIFEST sync, frontmatter, single-source test Five reviewer follow-ups on bradygaster#1292 (closes bradygaster#1289, refs bradygaster#1264): 1. (1292-a) Drift guard ran the copy loop FIRST and threw at the end if any source dir was missing — leaving a partial skills install on disk. Refactored to a pre-check pass that walks MANIFEST_SKILL_NAMES once for existence, throws if any source is missing, then runs the copy loop only if everything is present. Result: no partial state when a packaging bug ships. 2. (1292-b) Remediation text told the user to 'run scripts/sync-skill-templates.mjs from the squad repo root', which doesn't exist in an installed @bradygaster/squad-sdk tarball. Rewrote the message to target end users (try squad upgrade, report a bug if it persists) and kept the contributor hint as a parenthetical aside. 3. (1292-c) MANIFEST_SKILL_NAMES grew to 14 entries (squad-commands, squad-version-check, tiered-memory, iterative-retrieval, reflect, cross-squad added across PRs), but TEMPLATE_MANIFEST in packages/squad-cli/src/cli/core/templates.ts had only 10 — so squad upgrade would skip the new ones. Added matching entries for tiered-memory/iterative-retrieval/reflect/cross-squad (the 4 not already covered by other PRs). 4. (1292-d) packages/squad-cli/templates/skills/squad-version-check/ SKILL.md (and the 2 mirrors) shipped without ANY YAML frontmatter — just a freeform '**Confidence:**' Markdown line. isSkillContent() in consult.ts requires '---\\nname:...\\nconfidence:' front-matter to classify the file as a skill, so squad-version- check was misclassified in share / promote / merge flows. Added proper frontmatter (name, description, allowedTools, confidence, domain, source) to all 3 mirrors. 5. (1292-e) The regression test duplicated the MANIFEST_SKILL_NAMES list literal — adding a new skill would have required two edits to stay green. Exported MANIFEST_SKILL_NAMES from sdk/config and updated the test to import + iterate the same array the install loop reads. Future skill additions only need one edit. Verified: 26/26 init tests pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <Copilot@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…d coordinator-as-agent export (bradygaster#1274) Closes part of bradygaster#1272 — covers 3 of the 11 undocumented v0.10 user-facing features identified in the docs-gap audit. Files added: docs/src/content/docs/features/preset.md (205 lines) docs/src/content/docs/features/cross-squad-discover.md (158 lines) docs/src/content/docs/features/coordinator-as-agent-export.md (237 lines) Source verification: - preset.md sourced from packages/squad-cli/src/cli/commands/preset.ts - cross-squad-discover.md sourced from packages/squad-cli/src/cli/commands/cross-squad.ts and packages/squad-sdk/src/runtime/cross-squad.ts - coordinator-as-agent-export.md sourced from PR bradygaster#1180 body and packages/squad-sdk/src/repo-native/ scope Style matches existing feature pages (loop.md, plugins.md format). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…, reflect, error-recovery, teams-comms, fleet-dispatch, mcp-frontmatter, dual-mode, skill-security-scanner) + export-import --repo/--branch (bradygaster#1276) * docs: add feature pages for remaining 8 undocumented v0.10 features Closes the rest of bradygaster#1272 — covers the 8 user-facing features that had no dedicated docs page after PR bradygaster#1274 (which covered preset, cross-squad discover, and coordinator-as-agent export). New pages (8): docs/features/tiered-memory.md (hot/cold/wiki memory model) docs/features/reflect.md (in-session learning skill) docs/features/error-recovery.md (failure recovery skill) docs/features/teams-comms.md (Microsoft Teams adapter) docs/features/fleet-dispatch.md (/fleet hybrid dispatch) docs/features/mcp-frontmatter.md (--mcp-frontmatter flag) docs/features/dual-mode-deployment.md (SQUAD_POD_ID, dual-mode capabilities) docs/features/skill-security-scanner.md (markdown-aware skill scanner) Updated (1): docs/features/export-import.md (added --repo / --branch sections) Source verification: - tiered-memory.md ← packages/squad-cli/templates/skills/tiered-memory/SKILL.md - reflect.md ← packages/squad-cli/templates/skills/reflect/SKILL.md - error-recovery.md ← packages/squad-cli/templates/skills/error-recovery/SKILL.md - teams-comms.md ← packages/squad-sdk/src/platform/comms-teams.ts + changeset - fleet-dispatch.md ← packages/squad-cli/src/cli/commands/watch/capabilities/fleet-dispatch.ts - mcp-frontmatter.md ← packages/squad-cli/src/cli-entry.ts:346 flag + init flow - dual-mode-deployment.md ← packages/squad-sdk/src/ralph/capabilities.ts - skill-security-scanner.md ← scripts/security-review.mjs + changeset - export-import.md edits ← packages/squad-cli/src/cli/commands/import.ts:817 Style matches existing feature pages (loop.md, plugins.md, preset.md format). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(cspell): whitelist PKCE/MSAL/AKIA/runas + intentional 'typoo' example CI failure on docs-quality: cspell flagged 9 words across 3 of the new feature pages added by this PR. All 9 are legitimate technical terms or intentional content (not typos): - PKCE (RFC 7636 — OAuth Proof Key for Code Exchange) — 5 hits in teams-comms.md - MSAL (Microsoft Authentication Library) — 1 hit in teams-comms.md - AKIA (AWS access key ID prefix) — 1 hit in skill-security-scanner.md - runas (Windows runas elevation primitive) — 1 hit in skill-security-scanner.md - 'typoo' — an INTENTIONAL typo in an error-recovery example showing 'don't retry the user's typo by adding another character' Added all 5 to cspell.json. Verified locally: npx cspell --no-progress --dot 'docs/src/content/**/*.md' 'README.md' → 0 issues across 166 files. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…d recovery (bradygaster#1227) - Correct hook list (4 -> 6) in state-backends.md - Correct misleading claim that working-tree files remain as read-only reference (they're deleted after migration per migrate-backend.ts:218-235) - Add Steady-state safety net section explaining pre-commit + post-commit hooks - Add troubleshooting entry for refusing to commit two-layer state with recovery flow - Add post-upgrade verification checklist to upgrading.md Closes bradygaster#1226 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
… state (bradygaster#1230) * docs: clarify that .squad/casting/* files are identity, not two-layer state .squad/casting/* files (policy.json, registry.json, history.json) are AUTHORITATIVE IDENTITY files that should be committed to 'main' alongside team.md and routing.md. They define the agent universe, name registry, and usage history - fundamental team identity, not runtime mutable state. This change adds clarifying documentation to: - .gitignore: explicit NOTE that casting/* MUST NOT be ignored - .gitattributes: explicit NOTE that casting/* is identity, not append-only - init.ts: enhanced comments explaining casting/* classification This resolves confusion where casting files were misclassified as two-layer runtime state. Per squad.agent.md (the source of truth), casting files are 'Authoritative' and belong on main. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chore(changeset): add patch changeset for the casting=identity doc clarifications Policy Gates noticed the init.ts touch (pure comment additions clarifying that .squad/casting/* is identity, not mutable state) and asked for a changeset. Adding one — patch bump. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <copilot@github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Tamir Dresher <tamirdresher@users.noreply.github.com>
…an backends (bradygaster#1229) Adds .squad/decisions.md and .squad/agents/*/history.md to .gitignore (within a marker-delimited block) when stateBackend is 'two-layer' or 'orphan'. Removes the block when switching back to 'local'. Defense-in-depth complement to the pre-commit hook installed by squad upgrade --state-backend. - New helper module: packages/squad-sdk/src/config/gitignore-state.ts with addSquadStateGitignoreBlock + removeSquadStateGitignoreBlock - initSquad calls helpers based on options.stateBackend (adds stateBackend to InitOptions in SDK) - CLI runInit passes stateBackend to sdkInitSquad - migrate-backend calls helpers on backend transitions - Unit tests for helpers (add/remove idempotency, round-trip) - Integration tests for init and migration paths Closes bradygaster#1228 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…sation + docs feature pages) Mirrors the pattern of PR bradygaster#1219 (v0.10.0 promote). Brings into main: - 11 v0.10 stabilisation PRs (bradygaster#1292, bradygaster#1293, bradygaster#1295, bradygaster#1298, bradygaster#1300, bradygaster#1301, bradygaster#1302, bradygaster#1303, bradygaster#1304, bradygaster#1306, bradygaster#1307) — the full insider.1 release - Docs feature pages (bradygaster#1274, bradygaster#1276) — preset, cross-squad, coordinator-as-agent, tiered-memory, reflect, error-recovery, teams-comms, fleet-dispatch, mcp-frontmatter, dual-mode, skill-security-scanner - State-backend recovery docs (bradygaster#1227) - Casting=identity doc clarification (bradygaster#1230) - Conditional .gitignore for two-layer backend (bradygaster#1229) - Preset apply scaffolding (bradygaster#1293) and related work - New blog post about the v0.10 stabilisation effort - Docs deploy will now publish the updated feature pages to bradygaster.github.io/squad/ Safe to merge: package.json stays at 0.10.0 (the v0.10.0 git tag already exists, so the squad-release workflow will skip release creation). npm publish is workflow_dispatch only — not triggered. # Conflicts: # .github/dependabot.yml
Covers the 11 stabilisation PRs (bradygaster#1292, bradygaster#1293, bradygaster#1295, bradygaster#1298, bradygaster#1300, bradygaster#1301, bradygaster#1302, bradygaster#1303, bradygaster#1304, bradygaster#1306, bradygaster#1307), how to install the insider (@bradygaster/squad-cli@insider), the end-to-end smoke test that validates the whole stack, and what's still open (bradygaster#1308 slimming, bradygaster#1309 tiered-memory runtime, bradygaster#1310 machine-wide /squad, bradygaster#1225 preset install, github/copilot-cli#3787 MCP preload). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Contributor
🛫 PR Readiness Check
PR Scope: 📦🔧 Mixed (product + infrastructure)
|
| Status | Check | Details |
|---|---|---|
| ❌ | Single commit | 42 commits — consider squashing before review |
| ✅ | Not in draft | Ready for review |
| ✅ | Branch up to date | Up to date with main |
| ❌ | Copilot review | No Copilot review yet — it may still be processing |
| ✅ | Changeset present | Changeset file found |
| ✅ | Scope clean | |
| ✅ | No merge conflicts | No merge conflicts |
| ✅ | Copilot threads resolved | No Copilot review threads |
| ❌ | CI passing | 2 check(s) still running |
Files Changed (187 files, +15359 −377)
| File | +/− |
|---|---|
.changeset/bundle-missing-skills-1289-1264.md |
+39 −0 |
.changeset/casting-identity-not-state.md |
+5 −0 |
.changeset/conditional-state-gitignore.md |
+10 −0 |
.changeset/fix-1126-skills-to-github-skills.md |
+68 −0 |
.changeset/fix-1296-stop-mcp-home-pollution.md |
+40 −0 |
.changeset/fix-1299-fact-checker-full-plumbing.md |
+77 −0 |
.changeset/fix-1299-fact-checker-roster-instructions.md |
+54 −0 |
.changeset/fix-1305-state-backend-handshake.md |
+67 −0 |
.changeset/fix-fact-checker-auto-scaffold.md |
+16 −0 |
.changeset/fix-permission-contract.md |
+6 −0 |
.changeset/fix-release-pipeline-versions.md |
+14 −0 |
.changeset/fix-skill-squad-rename-to-squad-help.md |
+49 −0 |
.changeset/fix-squad-slash-command.md |
+76 −0 |
.changeset/fix-squad-spawning-routing.md |
+40 −0 |
.changeset/fix-yaml-escaping-skill.md |
+8 −0 |
.changeset/init-prompt-copilot-member.md |
+10 −0 |
.changeset/memory-tools-mcp-exposure.md |
+5 −0 |
.changeset/preset-apply-wires-team-1288.md |
+38 −0 |
.changeset/registry-subcommand.md |
+20 −0 |
.changeset/wire-cross-squad-communication-skill.md |
+53 −0 |
.gitattributes |
+6 −0 |
.github/agents/squad.agent.md |
+95 −13 |
.github/dependabot.yml |
+65 −4 |
.github/workflows/squad-agents-ai-ci.yml |
+91 −0 |
.github/workflows/squad-agents-ai-release.yml |
+182 −0 |
.github/workflows/squad-docs-links.yml |
+34 −34 |
.github/workflows/squad-impact.yml |
+1 −0 |
.github/workflows/squad-npm-publish.yml |
+25 −0 |
.github/workflows/squad-pr-nudge.yml |
+3 −3 |
.github/workflows/squad-pr-readiness.yml |
+1 −1 |
.github/workflows/squad-repo-health.yml |
+1 −0 |
.gitignore |
+15 −2 |
.squad-templates/fact-checker-charter.md |
+83 −0 |
.squad-templates/fact-checker-policy.md |
+104 −0 |
.squad-templates/spawn-reference.md |
+1 −1 |
.squad-templates/squad.agent.md |
+128 −15 |
.squad/skills/cross-squad-communication/SKILL.md |
+399 −0 |
.squad/skills/cross-squad/SKILL.md |
+66 −6 |
.squad/skills/iterative-retrieval/SKILL.md |
+165 −0 |
.squad/skills/reflect/SKILL.md |
+229 −0 |
.squad/skills/release-process/SKILL.md |
+2 −2 |
.squad/skills/squad-commands/SKILL.md |
+0 −0 |
.squad/skills/squad-help/SKILL.md |
+97 −0 |
.squad/skills/squad-version-check/SKILL.md |
+169 −0 |
.squad/skills/squad/SKILL.md |
+299 −0 |
.squad/skills/tiered-memory/SKILL.md |
+221 −0 |
CHANGELOG.md |
+8 −0 |
README.md |
+4 −0 |
Squad.Agents.AI.slnx |
+11 −0 |
cspell.json |
+3 −1 |
| ... | +137 more files |
Total: +15359 −377
This check runs automatically on every push. Fix any ❌ items and push again.
See CONTRIBUTING.md and PR Requirements for details.
… table CI failure on dev tip (567f447, Squad CI run 27488323855): test/docs-build.test.ts > 'all code blocks are properly fenced (even count of backticks)' → expected 1 to be 0 test/docs-build.test.ts > 'code blocks contain language specification or valid content' → expected 1 to be greater than 1 Root cause: a 4-backtick table cell intended to display a literal triple-backtick: | Inside a fenced code block (\\\\ \\\ \\\\) | Suppressed | made the regex /\\\/g see 5 triple-backtick occurrences across the file (instead of the 2 from the real bash example), tripping both the even-fence check and the line-count > 1 check. Rephrased the table to say 'three backticks' / 'single backtick' in prose — no embedded delimiters, no need to defend against the markdown fence escape mechanism. Reads cleaner anyway. Verified locally: 22/22 docs-build tests pass; npm run build in docs/ completes (171 files emitted; pagefind indexes 168 pages, 6911 words). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The repo's cspell.json is en_US — 'Stabilisation' fails docs-quality CI (unknown word, 3 occurrences). Switch to 'Stabilization' to match the existing dictionary without polluting it with one-off British words.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Promotes
devtomainfor the v0.10.1 docs release. Mirrors the pattern of #1219 (v0.10.0 promote).Brings into main:
@bradygaster/squad-cli@0.10.0-insider.1release.gitignorefor two-layer backend (fix(state-backend): conditional .gitignore for two-layer/orphan state files #1229)032-v010-stabilisation-insider.mdcovering the 11 PRs, install instructions, the smoke test, and what's still openWhy now: the public docs site (
bradygaster.github.io/squad/) is gated on push-to-mainand currently sits at the v0.10.0-era content (commitec3a221, 2026-06-07). Everything shipped since then — including all the feature pages users would search for after installing the insider — is invisible to anyone browsing the site.Safety
package.jsonstays at0.10.0(no version bump)v0.10.0git tag already exists, sosquad-release.ymlwill skip release creationworkflow_dispatchonly — not triggered by this mergesquad-docs.ymlwill run and deploy the updated sitesquad-ci.ymlruns on main pushes too — already green on dev tip567f4475Merge conflict resolved
One conflict in
.github/dependabot.yml(additive — main added npm+github-actions ecosystems, dev added two nuget ecosystems forSquad.Agents.AI). Resolved as a union of all four ecosystems.After merge
Followups (not in this PR)
squad.agent.mdphase 1 (waiting on review)Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com