Documentation Usage
On this page
Consumer Guide

Running the Squad

The Squad Coordinator routes your request to a cast of HVE Core agents, runs eligible roles in parallel, and persists roster, routing, decisions, and history under .copilot-tracking/squad/.

Invoke the coordinator#

Use the matching Squad agent's conversation for requests, not your system shell. In VS Code Copilot Harness, choose the agent from the agents dropdown; CLI and App also use the corresponding agent. See Getting Started for installation and your first conversation.

/squad request="add input validation to the login form"

Using VS Code Copilot Harness? Select Squad Coordinator from the agents dropdown and send the request text shown in the selected VS Code tab without the /squad prefix. Each host tab names the matching agent for federation, document, governance-report, and learning workflows.

Optional inputs#

  • profile=default|full|security|design|accessibility|architecture|azure|modernization|compliance|operations|product — seeds which cast is created on first run. If omitted on a fresh project, the coordinator inspects your repo and proposes a recommended profile before creating anything.
  • pack=power-platform, pack=m365-copilot, or pack=aws — adds a technology vertical's specialist roles on top of the profile. A pack never replaces the profile, and you can apply more than one (comma-separated). See Packs below.
  • tier=fast|default — a per-turn model-tier hint that overrides the coordinator's cost-first defaults.
  • routing=off|ranked|economy|manual — how each role's model is chosen, saved in team.md until you change it. off (default) applies no policy; ranked picks the model that best fits each role's work among the models your host offers; economyPre-release only v0.19.0-pre is ranked with cheaper picks for five implementation roles, after your consent; manual asks you to pick, with suggestions pre-filled. See Model selection per role below.
  • discovery=quick|standard|deep|skip — runs the discovery gate at that depth without being asked, or skips it. See Discovery gate below.
  • owner=<Member Name> — picks a specific named member when two rows in team.md share the same Role (for example owner=Beta when the roster has two developer rows).
  • mode=autonomous|autopilot — the autonomy mode for this turn. Omit it to run interactively, approving each step.
  • cost-ceiling=<positive USD>|unset — sets, replaces, or explicitly removes the current run's estimated model-spend ceiling. Omission inherits an active ceiling only within the same run. See Cost admission control below.
/squad request="threat-model the auth service" profile=security
/squad request="design the approvals app" profile=architecture pack=power-platform
/squad request="summarize the data layer" tier=fast
/squad request="reduce onboarding drop-off" discovery=standard
/squad request="build the booking service end to end" mode=autopilot cost-ceiling=20
/squad request="run security research and implement" routing=manual
WatchRunning a single squad end to end from the /squad entry point.

Autonomy modes#

How much the squad does before it asks you:

ModeHow to run itWho approves what
Interactive (default) no mode flag You approve each step (research, plan, implement, review). A ping fires at every step gate.
mode=autonomous mode=autonomous A narrow validator loop: the council re-validates one implementer output (max 2 cycles), then returns.
mode=autopilot mode=autopilot The squad runs research → plan → implement → review on its own and asks you only for impactful actions (deploy, git push, merge, schema/data changes) and to validate the final outcome.

Autopilot is the "tell it once, let it run" mode: it sequences the whole pipeline autonomously but always stops for a human before anything irreversible and before release. The two impactful/final stop-points fire a notification through the approval channel you choose at build time (interactive mode pings you at every step instead).

Autopilot hand-off pipelining#

Under mode=autopilot, the coordinator dispatches stage N's Scribe hand-off and stage N+1's role together, as two calls in one parallel tool-call block, whenever no barrier applies and three conditions hold: stage N's own artifact is confirmed on disk, the host's subagent-dispatch tool can be called more than once in one parallel tool-call block (VS Code's runSubagent, or Copilot CLI's task tool with or without mode: background), and pipelining has not been disabled by a prior verification failure in this run. Handing off to the Scribe alone and waiting is a defect in that case.

A cost-ceiling does not turn pipelining off. The Cost Preflight round that admits stage N+1 runs between the two parallel blocks and counts stage N's not-yet-recorded spend as a pending reservation, so the ceiling never under-counts spend while a hand-off is in flight. An inner run under untargeted federation autopilot pipelines at its own sub-squad root too.

Pipelining remains off in the following cases:

  • Watch Mode
  • The squad is a federation root (marked by presence of federation.md)
  • The active Cost Preflight round is approved-over-ceiling, whose dispatch units stay sequential
  • The host has no subagent-dispatch tool that accepts more than one call per block
  • After a pipelined hand-off (one that ran beside a role) has failed verification in this run; a failed hand-off that ran alone is corrected without turning pipelining off

When pipelining is off, the coordinator dispatches stage N's Scribe hand-off, waits for it to complete and be verified, and only then dispatches stage N+1 — exactly as in prior versions. When pipelining is active, stage N+1 starts while stage N's hand-off is in flight, but stage N+2 does not start until stage N's hand-off has returned and passed verification.

Verification and safety gates#

A bare Measure-SquadLedger.ps1 -Check is not sufficient for pipelined verification. Instead, the coordinator takes a pre-dispatch snapshot of the target history file's heading count, then verifies using -ExpectedHistoryCounts with that snapshot plus the entries this hand-off is expected to add. The coordinator also uses -BaselinePath to preserve a content-level baseline (Length, SHA-256, heading count) of every deliverable written so far this run, allowing detection of corrupted or modified prefixes in subsequent writes.

When a pipelined hand-off fails verification, pipelining is disabled for the rest of the run. The bad write is never rewritten by the Scribe; instead, a new append-only correction entry is dispatched, and the affected deliverable is restored by re-dispatching its owning role (not by editing history). The run does not cross the next barrier until a human approves the fix.

.copilot-tracking/squad/ and its contents are git-ignored, so ledger state is local evidence, not part of reviewed history. The delivered code, plans, and review records in plans/, research/, reviews/ and project files are tracked normally.

Benchmark harness#

An opt-in paired benchmark harness exists at tests/tier1/benchmark/Invoke-PipeliningBenchmark.ps1 (requires COPILOT_GITHUB_TOKEN). The live benchmark has not yet produced a baseline result, so pipelining behavior is described here and in the squad source references; no performance claim is made.

Cost admission control#

cost-ceiling is an optional ceiling on estimated model spend for one run. Initialization is outside the ceiling: the confirmed setup Scribe dispatch creates the roster, state, and pricing files and records that setup spend without consuming a ceiling slot. After initialization, before the first work dispatch and every later round, Cost Preflight builds a demand manifest from planned roles, dispatch classes, fixed model rates, orchestration, maximum conditional cycles, and eligible calibration. It does not quote billed cost, cap GitHub's invoice, or govern the Azure resources your implementation may create.

remaining USD      = max(0, ceiling USD - accumulated estimated spend)
projected cost USD = sum(calibrated planned-dispatch estimates)
admission cost USD = projected cost USD × 3.0

The factor-of-three admission reserve is a conservative policy allowance for uncertain future token use, not a statistical confidence interval. Displayed totals are rounded only after the row estimates are summed. A forecast reaches medium confidence only when demand is bounded, models and rates are known, the rate table is valid, and calibration matches the current estimator revision. Otherwise the squad reports cannot-confirm rather than presenting an optimistic answer.

Set, inherit, replace, or remove a ceiling#

InputEffective behavior
cost-ceiling=20 Set or replace the active run's ceiling with $20.
Argument omitted, same run Inherit the active positive ceiling. Omission never silently removes a guard.
cost-ceiling=unset Explicitly remove the ceiling while preserving accumulated consumption totals.
Argument omitted, new run Start as not-requested; no cost-ceiling comparison or stop applies.

Inheritance is bound to the recorded run ID. A later request that continues that run keeps its ceiling; a new autopilot topic, Watch event, or federation meta-run gets a new ID and does not inherit one. Estimated consumption is still recorded when no ceiling is active, and all non-cost gates continue to apply.

# Set a $20 ceiling for this run
/squad request="implement the approved plan" mode=autopilot cost-ceiling=20

# Same run: $20 remains active because omission means inherit
/squad request="apply the review fixes"

# Same run: remove the guard explicitly
/squad request="continue without a cost ceiling" cost-ceiling=unset

What each decision means#

DecisionMeaningCan work dispatch?
not-requested No effective ceiling exists for this run. Yes, subject to the normal non-cost gates.
within-ceiling The conservative admission cost fits the remaining amount. Yes, but only the slots named by that round.
over-ceiling The known forecast exceeds the remaining amount, or accumulated spend has reached the boundary. No. Before the boundary, the user may choose bounded proceed.
approved-over-ceiling The user accepted a known overage for the unchanged demand and pricing inputs. Yes, one sequential dispatch unit at a time while spend remains below the ceiling.
cannot-confirm Demand, model pricing, rate-table shape, or calibration cannot support a defensible forecast. No. Change the uncertain inputs; approval cannot waive missing evidence.

Proceeding after an over-ceiling forecast#

Before asking, the squad shows the ceiling, accumulated estimated spend, remaining amount, projected remaining-demand cost, conservative admission cost, and the stop limitation. If you proceed, it preserves the original over-ceiling record and appends an auditable approved-over-ceiling round linked to your approval. Approval applies only to the unchanged manifest and pricing basis; expanded, repriced, or low-confidence demand opens a new gate.

The ceiling is checked between dispatch units. A model call already in progress cannot be interrupted. The final child and its mandatory Scribe accounting handoff can therefore take the recorded estimate above the ceiling. The coordinator then records a terminal over-ceiling round and starts no later child.

Reaching the boundary does not block the project forever. To resume, set a new positive ceiling above current accumulated spend, explicitly remove the ceiling with cost-ceiling=unset, reduce or reprice the remaining demand and run a new preflight, or begin a new run. Re-approving the already exceeded value is deliberately not an option, because it would no longer define a stopping boundary.

Examples with accumulated spend#

Current stateNext requestResult
No prior ceiling; estimated spend is $10.80 cost-ceiling=10 on the same run Remaining is $0.00 and the new request does not dispatch until the ceiling changes or is removed.
Ceiling is $20; estimated spend is $10.80 Ceiling argument omitted on the same run The $20 ceiling is inherited; $9.20 remains before considering the new demand.
Ceiling is $20; estimated spend is $10.80 cost-ceiling=unset The guard is removed; $10.80 remains recorded and later work is not cost-gated.
A new run starts Ceiling argument omitted The new run records not-requested and proceeds without a cost ceiling.

Where to inspect the decision#

The latest compact decision is in state.json under currentRun.costPreflight. The reproducible record is the matching ## Cost Preflight entry in decisions.md, including its demand table, evaluated and permitted slot sets, reason, and Decision Ref. Every admitted history entry carries that Decision Ref and consumes one permitted slot exactly once. The accumulated estimated totals remain in consumption.md; model rates, dispatch-size assumptions, and calibration are in consumption-rates.md.

Federation scope#

Ordinary federation routing applies the supplied ceiling independently to every selected sub-squad, whether you name one with squad= or let meta-routing select one or several. Each selected sub-squad uses its own state, accumulated estimate, lifecycle, and stop boundary exactly like a plain squad. The federation root records routing and summary totals but keeps its aggregate Cost Preflight as not-requested.

Only federation-wide mode=autopilot without a squad= target applies one aggregate ceiling across all selected inner runs plus federation coordinator and root-writer orchestration. It uses the federation root's consumption-rates.md, does not also pass the ceiling into child runs, and counts completed meta slots across every round. An approved aggregate overage runs one sub-squad and root-writer unit at a time so the federation can stop at the shared boundary.

Discovery gate — when there is nothing written down yet#

Two gates run ahead of the work, and they fire on opposite triggers. The discovery gate fires when there is no input artifact and produces one; the intake gate fires when there is one and validates it. The brief a discovery session writes is itself an input artifact, so it flows straight into the intake gate.

no input artifact  →  discovery gate  →  brief  →  intake gate  →  research → plan → implement → review
   input artifact  →                              intake gate  →  research → plan → implement → review

Validation can be automatic. Ideation cannot. The intake gate fires on its own because assessing an artifact is something an agent can do alone. Discovery is offered rather than automatic, because the value of a brainstorm is your ideas and context. An automatic discovery gate would be AI brainstorming with itself and handing you a confident brief nobody agreed to.

When you are offered it#

The coordinator offers the gate only when all four hold:

  • The roster is product or full — those are the only profiles that seed analyst, which writes the brief.
  • No PRD, BRD, spec, story, design doc, transcript, or file you pointed at grounds the turn.
  • The turn advances toward a plan, a build, or a deliverable — not a question or a lookup.
  • The request states a goal (reduce onboarding drop-off) rather than a settled task (add a retry to the webhook client).

In every other profile the gate is silent — no offer, normal routing. That is the deliberate difference from the intake gate, which escalates when its role is missing: inputs that exist should not go unvalidated, but a brainstorm nobody asked for is not a check being skipped. You are asked once per topic; declining is recorded and never re-offered.

Passing discovery= always works, on any profile and even after you declined. It is a command rather than an offer, so a non-product squad will name the roles it must add and ask once before running.

Depth tiers#

DepthRoles dispatched, in orderProducesUse when
quick (default) analyst brief The goal is clear; only scope, users, and the success measure need settling.
standard designer → analyst framing, solution themes, brief The problem itself is open and several directions are worth exploring first.
deep designer → challenger + experimenter → analyst framing, themes, objections, riskiest assumption, brief The direction is expensive or hard to reverse and deserves a pressure-test and a cheap test.
skip none a Depth: skip verdict recording the declination You do not want a session, or the framing is already settled elsewhere.

deep needs challenger, which only full seeds. Choosing it in a product squad prompts the coordinator to add the role or run standard instead — it never silently drops a role from a tier you chose.

What you get#

The dispatched roles interview you, one question at a time, and stop rather than guess when they cannot reach you. Only the analyst writes a file: a short brief at <date>-<topic-id>-brief.md in the analyst's deliverable root, carrying the problem, why now, scope boundaries, the success measure, the options considered, the chosen direction, assumptions, and open questions. A ## Discovery Verdict lands in decisions.md alongside it.

The discarded options are the part worth protecting. A brainstorm's durable value is not the idea that won — that survives on its own — but the record of what was rejected and why, which is what stops the squad relitigating the same directions three turns later.

The gate never runs on an unattended path. There is nobody there to answer the offer, so the triggering payload becomes the input artifact and the intake gate assesses that instead.

Requirements intake gate#

When a run is grounded in requirement or input artifacts — a PRD, BRD, spec, user story, design doc, transcript, or a file you point the squad at — the coordinator runs an intake gate before it plans or builds, checking those inputs for completeness, clarity, testability, consistency, and scope. It records an ## Intake Readiness Verdict in decisions.md (Ready, Ready-With-Gaps, or Not-Ready).

On Not-Ready the squad does not build on shaky inputs: it dispatches the analyst or product-owner to fill the blocking gaps and re-validates (capped at two cycles), and escalates to you when a gap needs a human decision. When no input artifact grounds the run, the gate is a silent no-op. It ships with the product and full profiles; other profiles are offered the role when a run turns out to be requirements-driven.

When the input is a brief the discovery gate just produced, the validator is resolved to a different agent than the one that wrote it — the PRD Quality Reviewer checking a PRD Builder brief, for instance. A gate that validates its own output is a formality, not a check.

Approving remotely (unattended / VM runs)#

If you run the squad on a VM for a long job, pick the github-issue approval channel at build time. At each gate the squad opens a GitHub issue, assigns and @mentions you (so you get a GitHub mobile push), and waits. You approve from your phone with a comment — /approve, /approve-all, /changes: <note>, or /stop — or a squad/* label, without touching the VM. Only your registered handle (or a repo collaborator) can approve, and only those keywords act.

The other channels are webhook (an outbound Teams/Slack/Discord ping only) and in-chat (the default, which needs you at the PC). No channel requires the package to ship an email or chat transport — when a channel's tooling is absent it degrades to an in-chat approval, and the squad never proceeds on a timeout.

Remote approval setup (one-time, only for github-issue)#

Local and in-chat runs need nothing extra. To approve remotely from a VM run, set up the channel once:

  1. Authenticate GitHub on the run host. Either run gh auth login (the gh CLI is sufficient on a headless VM) or configure the official github MCP server. The package ships a reference entry in .github/skills/squad/mcp.template.json you can merge into your .vscode/mcp.json; the GitHub MCP is preferred when present, and the squad falls back to gh, then to in-chat. The token needs repo + issues scope.
  2. Install the approval watcher. Copy the reference workflow .github/skills/squad/github-approval-watcher.workflow.yml to .github/workflows/squad-approval-watcher.yml in the repo that hosts your approval issues, then commit it. It relays your /approve, /approve-all, /changes:, or /stop reply back so the run resumes — and only an authorized handle's recognized keyword acts (free-form comment text is never executed as a command).
  3. Pick github-issue at build time and give the coordinator the GitHub handle to @mention and the owner/repo for approval issues (defaults to the current repo).

Watch Mode — trigger the squad from a new issue#

Watch Mode is the event-driven, "continuous AI" side of the squad: instead of you typing /squad, a repository event starts the run. The shipped pattern turns a new issue labeled squad/auto into a headless mode=autopilot run that opens a draft pull request which closes the issue. It reuses everything you already configured — the autopilot pipeline, the council, and the github-issue approval channel — so a gate still pauses for your approval from a phone.

Diagram source

flowchart TD
    A["Issue labeled squad/auto"] --> B{"Write collaborator?"}
    B -- no --> X["Ignored, comment left on issue"]
    B -- yes --> C["Copilot CLI runs Squad Coordinator with mode=autopilot"]
    C --> D["Profile inferred from the issue (fallback: default)"]
    D --> E["Research, Plan, Implement, Review"]
    E --> F{"Impactful or Risk Gate?"}
    F -- yes --> G["Approve from phone via github-issue"]
    G --> E
    F -- no --> H["Open DRAFT pull request that closes the issue"]
    H --> I["You review and merge"]
      

The issue title and body are always treated as data, never instructions: the run reads them as the task description and never as commands that change its roster, routing, gates, or approvals. The run opens a draft PR only — it never merges, force-pushes, or deploys; those stay human-approved gates, backed by your branch protection.

Enable Watch Mode (one-time)#

  1. Create a Copilot token. Generate a fine-grained personal access token with the Copilot Requests permission and add it as the repository secret COPILOT_GITHUB_TOKEN. The built-in Actions token cannot authenticate Copilot, so this dedicated secret is required.
  2. Protect your default branch. Require a pull request and review before merge, so the squad's draft PR can never merge itself.
  3. Allow Actions to open pull requests. In Settings → Actions → General → Workflow permissions, enable "Allow GitHub Actions to create and approve pull requests." Without it, the squad can push its branch but GitHub blocks the draft PR with a 403 — the run finishes with the branch created but no PR. The workflow's pull-requests: write permission is not sufficient on its own. (This setting also lets Actions approve PRs; your branch protection keeps merges human-gated. For tighter scoping, use a dedicated PAT or GitHub App token for PR creation instead of this toggle.)
  4. Install the trigger workflow. Copy the reference workflow .github/skills/squad/squad-watch.workflow.yml to .github/workflows/squad-watch.yml, review it, and commit it.
  5. Install the approval watcher (if you have not already) so gate approvals flow back: copy .github/skills/squad/github-approval-watcher.workflow.yml to .github/workflows/squad-approval-watcher.yml.
  6. Label an issue squad/auto to start a run. Only a repository collaborator with write access can trigger it; an unauthorized label is ignored and noted on the issue.

Create and apply the squad/auto label#

The trigger is an ordinary GitHub label named exactly squad/auto. Create it once, then applying it to any issue starts a run — anyone with write access can do both. In the GitHub UI: Issues → Labels → New label, name it squad/auto, and save. Or with the gh CLI:

gh label create squad/auto --description "Hand this issue to the squad" --color 1D76DB
gh issue edit 42 --add-label squad/auto

Labeling is the signal: the issues: [labeled] event fires, the workflow checks the label is squad/auto and the labeler has write access, and the run begins. One run stays active per issue (a re-label will not start a second, competing run). The squad/auto trigger label is separate from the squad/* approval labels (squad/approved, squad/stop, …) the approval watcher reads at a gate.

Watch Mode is opt-in and in-repo only for now: an unlabeled issue does nothing, and pull requests from forks never start a privileged run (the workflow never uses pull_request_target).

Optional: a New Issue template for squad/auto#

Hand-labeling works fine, but a repository can also add a New Issue form that pre-applies the squad/auto label at creation, so filing a squad task is a single step. Copy the reference form .github/skills/squad/squad-task.issue-template.yml to .github/ISSUE_TEMPLATE/squad-task.yml, review it, and commit it — this adds a "Squad task" option to the repository's New Issue page with fields for the task, optional acceptance criteria, and an optional profile hint. This is purely a convenience: it is entirely optional, and an ordinary issue labeled by hand starts a run exactly the same way.

Other triggers (beyond a new issue)#

A new labeled issue is just the first entry in Watch Mode's event-to-intent map. The contract (.github/instructions/squad/squad-watch-mode.instructions.md) defines how any repository event becomes a routed run: the trigger only supplies the event payload as data, and the coordinator's routing table picks the role. The shipped reference workflow wires all of them in one file — a single Prepare run step authorizes the actor, enforces fork-safety, and builds the routed prompt for whichever event fired.

TriggerHow it firesWhat the squad doesShipped?
New issue Apply the squad/auto label mode=autopilot → draft PR that closes the issue Yes
Manual dispatch Actions tab → Run workflow (a request or an issue number) mode=autopilot or a routed run Yes
Pull request Apply a squad/review label to a same-repo PR Routes to the tester role → review comments on the PR Yes
Comment command Comment /squad <request> on an issue or PR Routes per the command → per-role outcome Yes
Scheduled sweep The cron in the workflow A maintenance sweep (dependency/docs/SSSC) → draft PR or issue Yes
Push A push to the configured branch pattern A validation council → verdict (opens an issue only on Stop) Yes

Every trigger runs through the same guardrails: an opt-in gate (a squad/* label or an authorized /squad keyword), an authorized actor, the payload treated as data, human-approved gates for anything impactful, and same-repo only (fork PRs are skipped and pull_request_target is never used). Two triggers are time/branch based, so tune them for your repo before enabling — and delete any trigger you do not want:

# In .github/workflows/squad-watch.yml

on:
  schedule:
    - cron: '0 6 * * 1'      # when the maintenance sweep runs — adjust or remove
  push:
    branches: ['release/**'] # which pushes get a validation council — adjust or remove

The issues, pull_request, issue_comment, and workflow_dispatch triggers need no tuning — they are gated by labels and the /squad keyword, so they stay dormant until you opt an item in.

Every run gets its own sub-squad#

Unattended runs are only trustworthy if you can see what they did. So every Watch Mode run executes inside a federation sub-squad dedicated to its triggering event. Issue #123 gets members/issue-123/, with its own roster, decisions log, per-agent history, and consumption ledger. Nothing from one automated run bleeds into another's trail, and months later you can still open a folder and read exactly which roles ran, what they decided, and why.

You do not have to set the federation up first. Watch Mode bootstraps whatever is missing before the run starts:

What your repo hasWhat Watch Mode does
Nothing yet Creates the federation, then the event's sub-squad
A plain single squad Auto-promotes it into a federation (your existing state relocated intact, logs preserved byte-for-byte), then adds the event's sub-squad alongside it
Already a federation Adds the event's sub-squad
The event's sub-squad already exists Reuses it and resumes — a re-labelled issue or a new PR push stays in one trail

The names are deterministic, so you always know where to look:

issue-123                   # an issue, or a /squad comment on it
pr-456                      # a PR review, or a /squad comment on the PR
sweep-2026-07-27            # a scheduled maintenance sweep
push-release-2-0-a1b2c3d    # a push to release/2.0 at commit a1b2c3d
dispatch-9911223344         # a free-form manual dispatch (workflow run id)

Two safety properties matter here. First, a sub-squad name is a folder path, so it is derived only from structural event metadata — issue and PR numbers, branch refs, commit shas, the run id, the date. Never from an issue title or a comment body, which anyone can write. Second, the bootstrap never writes into a sub-squad it did not create: if the derived name collides with one of your own, the run comments on the source issue and stops instead of overwriting it. Watch-created sub-squads are marked Owner=watch-mode in federation.md and registered with a narrow, ref-keyed route, so your interactive /squad-federation requests never land in one by accident.

These sub-squads are kept — they are the audit trail, so nothing prunes them automatically. Archiving or removing one is a deliberate thing you ask for.

Finding the details behind a gate#

When the squad pauses at a gate — a Cost Preflight, discovery, intake-readiness, or council verdict, an impactful action, or the final outcome — the chat message stays deliberately short so it does not bury the conversation. The full reasoning lives in .copilot-tracking/squad/decisions.md, which is append-only: a new ## Council Verdict entry is inserted in the file (often in the middle, next to earlier entries), not always at the end. To save you hunting for it, every gate message carries a Decision Ref — a deep link straight to the exact section:

.copilot-tracking/squad/decisions.md#council-verdict-2026-07-07-residual-controls
.copilot-tracking/squad/decisions.md#cost-preflight-2026-09-13-run-001-round-002

The anchor is the Markdown heading of the verdict entry (lower-cased, spaces to hyphens), so opening the link in VS Code or on GitHub Pages jumps you straight to the verdict, its findings-by-role table, and the conditions — no scrolling required. The gate message and the notification payload both include this Decision Ref; the State pointer to state.json and the history file remains as a fallback.

Where each gate records its details:

Diagram source

flowchart TD
    A["Gate reached (council / impactful / final)"] --> B["Short chat / notification message"]
    B --> C["Decision Ref deep link"]
    C --> D["decisions.md#council-verdict-DATE-TOPIC — verdict, findings, conditions"]
    B -. fallback .-> E["state.json + history — run state and audit trail"]
    B --> F["notifications.md — append-only ping log"]
      

First run (Init Mode)#

When a project has no .copilot-tracking/squad/team.md, the coordinator proposes a squad profile and asks whether to proceed. If you decline, you can pick a different profile or build a custom roster from a described menu of every available role — so you always choose from real, deployed agents and never invent one. It then asks for an optional approval channel (github-issue for remote/phone approval, webhook, or in-chat), then seeds team.md, routing.md, decisions.md, notifications.md, state.json, and a history/ directory. It never writes files before you confirm. After that, each /squad call routes against the seeded roster.

On a brand-new project (no squad yet), Init Mode first offers a choice: a single squad (the default) for one team across the repo, or a federation of several named sub-squads. Choosing a federation hands off to /squad-federation (see below); choosing a single squad keeps the flow above unchanged.

Federation — several sub-squads in one repo#

Federation lets one repository host more than one squad side by side — for example a product sub-squad for the business team and an azure sub-squad for the architects. It is opt-in and additive: a repository that never opts in behaves exactly like a single squad. Each sub-squad is an ordinary squad — same roster, routing, decisions, history, and consumption — only rooted at .copilot-tracking/squad/members/<name>/ instead of the top level.

# Build a federation (propose → confirm → create)
/squad-federation init

# Route a request to a specific sub-squad
/squad-federation request="draft the Q3 roadmap" squad=product

# Omit squad= and let meta-routing pick by keyword/domain
/squad-federation request="design the landing-zone network"
WatchFederating several sub-squads in one repository with /squad-federation.

A meta layer at .copilot-tracking/squad/ holds federation.md (the registry of sub-squads) and meta-routing.md (request pattern → sub-squad), plus a federation-level decisions and history trail. The Squad Federation Coordinator reads them, picks the sub-squad(s) — or honors your explicit squad=<name> — and runs each sub-squad's normal per-turn protocol scoped to its own root.

The coordinator decides which squad you are on by a simple rule: a federation.md at the top means a federation (use /squad-federation); a top-level team.md means a plain squad (use /squad as before). The two are mutually exclusive, so an existing single-squad project is untouched — until you choose to promote it (below).

Every sub-squad has a required, unique, lower-kebab-case name, because the name is at once its members/<name>/ folder and the squad=<name> selector you type. Init validates names before creating any folder and asks you to rename on a collision — it never silently reuses or overwrites a sub-squad directory. Profiles are proposed per sub-squad from your repo and request (just like a single squad), and you can accept, swap a profile, add or remove a sub-squad, or build a custom roster for any of them.

Promote a single squad to a federation#

If you started on an older version with a single squad and now want the federation shape for a more complex, multi-team or multi-domain project, you do not start over. Promotion adopts your existing squad into a federation as its first sub-squad, moving its state intact rather than rebuilding it.

# Promote the current single squad into a federation
/squad-federation promote

# Or ask the Squad Coordinator and accept its handoff
/squad request="I want to move this squad to a federation"

Promotion runs a propose → confirm → migrate → seed → route flow and never moves or writes anything before you confirm. On confirmation it relocates the whole top-level state tree — team.md, routing.md, decisions.md, history/, consumption, and the rest — into members/<name>/, preserving your append-only decision and history logs byte-for-byte, then seeds the meta layer (federation.md, meta-routing.md, and a federation-level decisions/history trail). That move removes the top-level team.md, so from the next turn /squad-federation owns turns and /squad detects the federation and defers.

It is safe and additive: a relocation, not a delete or rewrite; it refuses on a name collision or when a federation.md already exists; and a consumer who never promotes is completely unaffected. You can adopt more sub-squads alongside the promoted one in the same turn, or add them later (see below).

Add a sub-squad to an existing federation#

Federations grow. Once a federation exists, sending init to its coordinator (or just asking to add a sub-squad) runs Expansion Mode — the same init entry point builds a federation on a fresh project and expands one that already exists.

# Add a new sub-squad to the current federation
/squad-federation init request="add a security sub-squad for threat modeling"

Expansion proposes the new sub-squad (name, profile, roles) and, on your confirmation, seeds it under members/<new>/ and registers it — appending a row to federation.md and a route to meta-routing.md, plus a federation decision entry. It is additive and non-destructive: existing sub-squads are never edited or removed, and it refuses on a name collision. After it completes, the new sub-squad is routable by squad=<new> or by meta-routing keyword.

Autonomy modes work inside a targeted sub-squad. With squad=azure, autopilot runs that one sub-squad's full pipeline. Drop the squad= target for federation-wide autopilot: it orders the selected sub-squads by dependency (confirmed at the first gate), runs each one's standard autopilot in turn, lifts every Impactful-Action and Risk Gate to the federation level (attributed to the sub-squad that raised it), applies one aggregate cost-ceiling with the lifecycle and bounded approval behavior described in Cost admission control, and ends with a single consolidated final-outcome validation. Each sub-squad's inner pipeline is unchanged, and it never auto-releases.

# Target one existing sub-squad
      /squad-federation squad=azure mode=autopilot request="implement the approved infrastructure plan"

      # Or coordinate the work across the federation
      /squad-federation mode=autopilot request="implement the approved cross-squad plan"

Promote a learning (/squad-learn)#

Live agent memory always stays local to each consumer. When a squad run surfaces a durable, broadly applicable learning, /squad-learn drafts a sanitized candidate from consumer-local memory and opens a pull request to promote it. It never modifies live memory and never pushes without your explicit approval.

/squad-learn
/squad-learn target=upstream
/squad-learn target=tenant learning="re-read reviewer verdicts before re-dispatching"

The command walks through discover → sanitize → choose target → open PR. Two targets are offered: upstream promotes to the public package so the merged learning reaches every consumer, and tenant promotes to your organization's private tenant-internal repository so the learning stays inside the tenant. Both are gated by a human pull-request review, the defense against memory poisoning, data leakage, and context drift. The tenant target requires the private learnings repository to exist first (see the tenant scaffold); upstream works out of the box.

Search and export squad knowledge (/squad-document)#

/squad-document searches squad state — decisions, history, routing, roster, and project documentation — to answer a question or produce a focused document. Instead of reading decision logs and history files directly, you describe what you need in natural language and the command synthesizes a grounded answer written to a local file.

/squad-document request="summarize all council verdicts from last week"
/squad-document request="what did the architect decide about the data layer?" format=html
/squad-document request="produce a stakeholder briefing" format=docx outputPath=docs/briefing.docx
/squad-document request="list all escalations" squad=product

Inputs#

  • request — (required) what you want to find or document, in natural language.
  • format={md|html|pdf|docx} — output format (defaults to md). Falls back to Markdown when the requested format's tooling is unavailable.
  • outputPath=<path> — where to save the file. Defaults to docs/squad-document-<YYYY-MM-DD>.<ext>.
  • squad=<name> — in a federation, scope the search to a specific sub-squad. When omitted, searches across all sub-squads.

Every statement in the output is grounded in squad artifacts — the command cites source files and marks gaps as explicit Open Questions rather than inventing content. Squad state is read-only input; the command never modifies any state file.

Governance dashboard (/squad-governance-report)#

/squad-governance-report generates a self-contained HTML governance dashboard from squad state. It visualizes coordination activity, governance gates, cost distribution, role dispatch patterns, compliance indicators, and key outcomes so a developer or stakeholder can assess squad health at a glance — without manually reading decision logs or history files.

/squad-governance-report
/squad-governance-report output=docs/governance.html period=30d
/squad-governance-report squad=azure period=7d

Inputs#

  • output=<path> — where to save the HTML file. Defaults to docs/squad-governance-report-<YYYY-MM-DD>.html.
  • squad=<name> — in a federation, scope to a specific sub-squad. When omitted, aggregates across all sub-squads.
  • period={all|30d|7d} — time window to include (defaults to all).

Dashboard sections#

The generated report contains seven sections:

  1. Governance Gates — council verdicts, intake checks, human gates, and escalation counts.
  2. Council Verdicts — verdict distribution (Go / Go-With-Conditions / Stop) with findings by role.
  3. Cost Breakdown — estimated cost by role and model tier.
  4. Role Dispatch Activity — dispatch counts, models used, success rate, and autonomy tier distribution.
  5. Risk & Compliance — artifact evidence, test verification, impactful-action gating, and open escalations.
  6. Activity Timeline — chronological view of dispatches and decisions.
  7. Key Outcomes — deployments, issues created, tests run, files changed, and delivered capabilities.

The output is a single .html file with no external dependencies — all styles are inlined, so it renders correctly when opened in any browser or shared as an attachment.

PreviewA sample governance dashboard generated by /squad-governance-report.

Profiles#

The cast each profile seeds:

ProfileMembersUse when
defaultresearcher, lead, developer, tester, scribeGeneral-purpose work; recommended starting point
fullevery role in the cast except the opt-in roles and the four unbacked onesComplex, cross-cutting projects
securityresearcher, lead, developer, tester, security, supply-chain, rai, privacy, fact-checker, scribeSecurity, supply-chain, privacy, threat-modeling, and responsible-AI focus
designresearcher, lead, developer, tester, designer, accessibility, scribeUX/UI and product-design focus
accessibilityresearcher, lead, developer, tester, accessibility, designer, scribeAccessibility conformance as the goal itself — WCAG 2.2, Section 508, or EN 301 549 assessment and remediation
architectureresearcher, lead, developer, tester, architect, azure-architect, cost-manager, scribeSystem design and architecture focus
azureresearcher, lead, developer, tester, azure-architect, iac-author, deployer, asbuilt-author, azure-diagnose, architect, cost-manager, security, modernizer, scribeAzure build with IaC authoring, deployment, post-deploy documentation, troubleshooting, budget, and security oversight
modernizationresearcher, lead, developer, tester, modernizer, architect, azure-architect, iac-author, cost-manager, asbuilt-author, scribeLegacy uplift — framework and dependency upgrades, re-platforming, SQL or cloud migration
complianceresearcher, lead, developer, tester, security, supply-chain, vuln-manager, privacy, rai, accessibility, risk-manager, scribeConformance evidence is the goal — an audit, an attestation, or a customer security questionnaire
operationsresearcher, lead, developer, tester, azure-diagnose, performance, observability, asbuilt-author, iac-author, deployer, scribeRunning a deployed system — incidents, reliability targets, instrumentation design, and as-built documentation
productresearcher, lead, developer, tester, analyst, designer, product-owner, presenter, technical-writer, experimenter, data-scientist, intake-validator, scribeBusiness discovery and delivery — requirements, design thinking, roadmap, and stakeholder deliverables (often non-technical)

Every profile includes the methodology spine — researcher, lead, developer, and tester — plus scribe, so Research → Plan → Implement → Review runs in any profile. Each profile adds its specialist roles on top. Some roles are seeded only in full, among them challenger, which pressure-tests a plan and checks it against the research it rests on, and prompt-engineer, which authors and reviews prompt artifacts. Any role in the cast can also be added to any roster on request — a profile is a convenient starting set, not a ceiling.

Some roles are opt-in and appear in no profile at all, not even full, for one of two reasons. backlog-executor writes work items into a live Azure DevOps or Jira project, and a tracker write reaches a whole team — notifications, subscriptions, and webhooks fire the moment an item lands — so the squad never seeds that reach by default. qa-engineer, release-engineer, and every pack role are opt-in for a different reason: the agent that fills them is published elsewhere and simply is not there until you install it, and a roster should never advertise capability your project does not have. Either way the coordinator offers the role the first time you ask for work that needs it, naming what it would do and, where something must be installed, the exact command. Accept and it joins your team for good; decline and the squad tells you what it cannot do rather than quietly doing it badly. See Backlog writes below.

The council is sized to the work, not to a fixed quorum. Only full seeds every council role (architect, security, cost-manager, product-owner, rai), and no other profile needs to. A council dispatches only the roles for the lenses the work touches — two of them, all five, or rai alone — and records every lens it left out with the reason. When a needed council role is not on your roster, the coordinator offers it as a council extension. If your opening request already signals a council, the offer comes at Init, in the same confirmation as your profile; otherwise it comes when the council fires. In autopilot the squad asks only when a needed role is missing, and Watch Mode reports the role to add rather than adding it. Decline and the squad records a council waiver and carries on; the waiver never clears a Risk Gate or an impactful action.

Four roles are listed but unselectable, and they are listed on purpose: devrel, networking, gcp, and identity. There is no agent and no skill behind any of them, here or upstream, so a role would be a promise rather than a capability. Each says why and what would change it, which is more useful than a gap you discover halfway through a turn.

Packs#

A profile answers what kind of work is this. A pack answers what is it built on. You pick exactly one profile and layer zero or more packs on top, so a technology vertical composes with whatever concern you already chose — a Power Platform project that also needs an audit trail takes compliance plus the power-platform pack, rather than forcing a choice between them.

The difference is structural, not cosmetic. A profile carries the methodology spine and can deliver on its own; a pack carries specialists only and needs a profile underneath it. That is also why azure and modernization stay profiles: they behave as the dominant shape of a team rather than as an addition to one.

PackAddsUse when
power-platformpp-architect, pp-connectorThe project is built on Power Platform — Power Apps, Power Automate, Dataverse, Power Pages, or Copilot Studio
m365-copilotm365-agent-architect, m365-agent-integratorThe project is built on Microsoft 365 Copilot — declarative agents, TypeSpec agent definitions, API plugins, MCP-backed agents, or Microsoft Graph integration
awsaws-architect, aws-diagnoseThe project is built on AWS — Lambda and serverless, ECS or EKS, CDK, SAM, CloudFormation, Organizations and landing zones, or a live AWS workload to triage

pp-architect designs the solution: which components to use, how environments and DLP policies are set up, how the Dataverse model and the solution lifecycle hang together. pp-connector builds custom connectors and wires them into Copilot Studio agents. Both advise and author files; neither runs pac against your tenant or publishes a connector, so nothing reaches a live environment without you doing it.

m365-agent-architect designs a Microsoft 365 Copilot declarative agent: what it should be able to do, how its instructions and conversation starters read, and whether it is defined as a JSON manifest or in TypeSpec. m365-agent-integrator connects that agent to the systems behind it — MCP server tools, sign-in through Entra, and Microsoft Graph — and plans the tenant rollout. As with Power Platform, both stop at the handoff: neither provisions an agent or publishes it to your tenant.

aws-architect designs AWS workloads — which services, how the accounts and landing zone are laid out, and the CDK, SAM, or CloudFormation to build it — judged against the AWS Well-Architected pillars. aws-diagnose works a live incident read-only, from the CloudWatch alarm through metrics, logs, and traces to a root-cause hypothesis it can show you the evidence for; it recommends a mitigation and never applies one. Because AWS is a pack rather than a profile, a multi-cloud project takes azure and the aws pack together and gets both, instead of being asked to choose. There is no gcp pack: nothing upstream covers Google Cloud, and the squad says so rather than implying general multi-cloud reach.

A pack is opt-in. Its roles are filled by agents published in github/awesome-copilot rather than by this package, so hve-squad references them instead of shipping them — you install a pack's resources deliberately, and no consumer carries a vertical they never asked for. The coordinator gives you the exact install command when you apply the pack, or the first time a request needs a role the pack would provide.

You rarely have to remember packs exist. The squad offers one the same way it offers a profile — on the first run when your repo carries the signals, or when your request simply names the domain (“turn this business plan into a Power Platform solution” is enough, even in a repo with no Power Platform files yet). It also offers one later, the first time a request needs a role only that pack provides. An offer is never an application: you confirm.

Ask the squad to drop a pack when you are done with that work and it comes back off the roster. Removal only takes out the roles that pack still owns — a role your profile or another pack also contributes stays — and it does not damage the record: the decision log and each agent's history are append-only, so removal adds an entry rather than erasing any. Anything those roles already produced stays on disk, and the resources stay installed, so re-applying the pack later costs nothing.

Some verticals are not packs#

Two domains arrive as extra reach on a role you already have, rather than as a pack, because no upstream agent behind them passed the squad's verification gate — and a pack needs roles, which need an agent. Power BI and Fabric (semantic-model review, DAX optimization, report design, Lakehouse fundamentals) sit with data-scientist. AI application engineering (Microsoft Agent Framework, Semantic Kernel) sits with developer.

There is nothing to apply for either. developer is in every profile, so the AI engineering side is always there. data-scientist is seeded by full and product; in any other profile, ask a Power BI or Fabric question and the squad will notice the role is missing and offer to add it, the same way it offers any other role. That works, but you find out at the moment you need it rather than when you build the squad — which is the honest cost of a vertical that could not become a pack.

Worked combinations#

The profile comes from the shape of the work and the pack from the technology, so the same pack turns up against several profiles. These are illustrations, not a fixed list — any pack goes with any profile:

What you are doingCommand
Greenfield Power Platform appprofile=default pack=power-platform
Power Platform app that has to produce audit evidenceprofile=compliance pack=power-platform
Designing an AWS workload before anything is builtprofile=architecture pack=aws
One estate spanning Azure and AWSprofile=azure pack=aws
On call for a live AWS workloadprofile=operations pack=aws
An M365 Copilot agent that handles personal dataprofile=security pack=m365-copilot
A Power Platform solution fronted by an M365 Copilot agentprofile=default pack=power-platform,m365-copilot

The operations plus aws row is the one a profile could never have served: operations already brings the Azure troubleshooter, and the pack puts the AWS one beside it, so a single squad triages both clouds. The last row is the other case a profile could not serve — two verticals at once, where a profile makes you pick one.

Profile, pack, or federation?#

Three things can add capability, and it is easy to reach for the wrong one. The rule is short:

One piece of work that needs extra expertise is a profile plus a pack. Those roles have to share a plan, a review, and the same conversation.

Two streams of work with separate deliverables and owners is a federation. Those teams need coordinating, not putting in the same room.

Take a Power Platform app that has to pass an audit. As profile=compliance pack=power-platform that is one squad: the Power Platform architect and the privacy role are dispatched against the same request, and the DLP decision and the data-retention decision are made together, in one plan and one review. Split the same job into a compliance sub-squad and a power-platform sub-squad and you get two teams, each with its own decision log and its own history, deciding one thing in two rooms that never met.

It is also worth knowing that a federation does not reach a technology vertical any faster than a plain squad does. Every sub-squad is seeded from a profile, so a vertical arrives on it by applying the pack — exactly as it would anywhere else. Building a sub-squad named after a vertical still needs the pack, and adds a duplicated research-plan-build-review core and a second set of state files for nothing extra.

Federate when there really are two products — say a Power Platform app and an Azure data platform, different owners, shipping separately. The first of those still carries the pack. See Federation above for how sub-squads work.

Azure execution layer#

The azure profile adds an Azure build-and-deploy capability modeled on a deployable Azure template repo, delivered the package way — as reference templates plus squad agents:

  • Squad Azure Architect authors the HLD/LLD (AVM modules, landing-zone patterns).
  • Squad IaC Author converts that LLD into Bicep or Terraform under infra/{track}/{project}.
  • Squad Cost Manager produces indicative estimates and WAF Cost Optimization findings.
  • Squad Deployer runs a read-only Azure Policy precheck (effective assignments and predicted denials), then what-if/plan, and finally the deploy — strictly behind the Impactful-Action Gate, never without your approval.
  • Squad As-Built Author inventories deployed resources via Azure Resource Graph, builds a compliance matrix from Azure Policy state, and drafts an operations runbook and backup/DR plan — all read-only, never deploys or mutates resources.
  • Squad Azure Diagnose queries Resource Health, Azure Monitor logs (KQL), and Resource Graph to correlate ranked hypotheses and recommend (never apply) remediations for unhealthy resources.

The azure-scaffold skill bundles documentation-only reference templates a squad agent copies into your repo: a dev container (Azure CLI + Bicep, Terraform + TFLint, gh, Node, Python), azure/login@v2 OIDC deploy workflows for Bicep and Terraform, a Setup-AzureOidc.ps1 wizard (Entra app registration, federated credentials, RBAC, GitHub secrets), a read-only Get-PolicyBaseline.ps1 plus a scheduled governance workflow, and the infra/bicep/{project} / infra/terraform/{project} convention. Nothing runs from the package — activation is always an explicit copy-and-commit into your repo, and authentication is OIDC (no stored secrets).

Azure MCP capability#

The Deployer precheck, As-Built Author, and Azure Diagnose all use the azure-resource capability, which prefers the official @azure/mcp server when configured and falls back to the az CLI and the Azure Resource Graph REST API automatically when it is not. The squad never blocks on a missing MCP for a read capability like this one.

To wire the Azure MCP server, merge the azure server entry from .github/skills/squad/mcp.template.json into your .vscode/mcp.json and reload VS Code. The server authenticates via az login (DefaultAzureCredential) — no stored secrets. You can ask the coordinator to scaffold this for your VS Code workspace:

/squad request="merge the squad MCP template into my VS Code workspace"

Backlog writes (Azure DevOps and Jira)#

The product-owner role plans a backlog and stops at a finalized handoff file. Turning that plan into real work items is a separate, gated step owned by the opt-in backlog-executor role — the same shape as the Azure Deployer: preview first, approve, then write.

  1. Ask. With a planned backlog in hand, ask the squad to create the items:
    /squad request="create these work items in Azure DevOps"
  2. Accept the role. If your squad does not carry backlog-executor, the coordinator offers to add it and names the tracker and project it would write to.
  3. Review the preview. The role reads your handoff file and shows every item it would create or update — type, title, parent, target project, and the fields it would set — plus the total count. Nothing has been written yet.
  4. Check the warnings. It also searches the live tracker for items that already match and flags probable duplicates with their existing IDs, and it strips internal planning references out of the outbound text so no tracking paths or placeholder IDs land in your backlog.
  5. Approve. One approval covers one batch. Change the handoff, re-run, or target a different project and you get a fresh preview and a fresh approval.

Writes are recorded item by item in a log file next to your handoff, so a batch that fails partway through resumes from the first unwritten item instead of creating duplicates. Nothing is rolled back automatically — whatever landed is reported back to you.

Two limits are deliberate. Writing needs the Azure DevOps MCP server (or, for Jira, the jira skill) configured; unlike the read capabilities, there is no fallback — the role stops and tells you what is missing rather than reaching your tracker by a route you never set up. And because a tracker write is an Impactful Action, an unattended Watch Mode run produces the preview and stops there; the write always waits for a person.

Modernization#

The modernizer role plans modernization work and routes it to the right execution engine, all from the single /squad entry point:

  • Same-stack modernization — framework and dependency upgrades, deprecated-API remediation, containerization, and Azure-migration readiness. The plan recommends the squad developer role for scoped edits, or Microsoft's official GitHub Copilot App Modernization extension and CLI for large batch upgrades.
  • Cross-stack re-platform — rewrites across languages or frameworks (for example, a Node.js backend rebuilt on .NET, or a React app rebuilt in Angular). The plan captures a behavior contract for the current system, sequences an incremental (strangler-fig) rewrite, and routes execution to the developer and architect roles under council review — never the official upgrade tooling.

Modernization runs at the confirm tier: the role produces a plan that gates implementation, and cross-domain phases route through the council before any code changes.

Branded PowerPoint decks#

The presenter role (seeded by the product and full profiles) generates decks from your content. Give it your branded .pptx once and every deck inherits your slide masters, layouts, theme colors, and fonts. The branding rule ships with hve-squad and switches on by itself — you never copy a file, edit a config, or restate the template on each request.

When you ask for a deck, the coordinator dispatches the PowerPoint Subagent, which runs the powerpoint skill's build_deck.py. Branding is applied through the --template flag (PowerShell -TemplatePath): the build inherits the template's slide masters, layouts, and theme, discards the template's own example slides, then adds only the slides defined in your content.

The template is everything. A polished deck comes from a well-built template far more than from the generator. Spend your effort on the master and layouts in PowerPoint, and the squad fills them in consistently.

1 — Prepare a branded template#

Open PowerPoint, build a 16:9 template, and save it as a .pptx with:

  • Slide Masters carrying your backgrounds, logo placement, and footer — set under View → Slide Master.
  • Named layouts the builder maps onto, at minimum Title Slide, Title and Content, and Section Header.
  • Theme colors and fonts defined in the theme (Slide Master → Colors / Fonts) so @theme_name references resolve to your brand palette.

You do not need to leave example slides in the file — a --template build discards them and keeps only the masters, layouts, and theme.

2 — Put it in a stable place#

The template lives at a fixed path so the squad always knows where to find it:

.github/brand/pptx-brand-template.pptx

You do not have to create that folder yourself. If you just hand the squad your .pptx (or point it at one), it offers to save a copy there for you.

3 — It applies automatically#

hve-squad ships the branding instruction as part of the package, so on apm install it lands at .github/instructions/pptx-brand-template.instructions.md and switches on by itself. Its applyTo matches **/.copilot-tracking/ppt/**, so the PowerPoint Subagent reads it every time it works on a deck — using your template as --template for full rebuilds and --source for partial ones. If no template is present yet, the builder does not quietly fall back to a plain deck: it asks whether you have a branded .pptx and offers to save it for you.

Full rebuild vs. partial rebuild. --template creates a new deck and keeps only masters, layouts, and theme — use it for new decks and full regenerations. To update a few slides in an existing deck, the builder uses --source with --slides instead. Never combine the two: with both, --template wins and every slide not listed is lost.

4 — Align content with the template (optional, technical)#

You can skip this — the squad handles it for you. For tighter control, declare the template and map layout names in content/global/style.yaml:

template:
  path: ".github/brand/pptx-brand-template.pptx"
  preserve_dimensions: true
layouts:
  title:   "Title Slide"
  content: "Title and Content"
  section: "Section Header"

Then in each slide's content.yaml, reference colors with @theme_name rather than hardcoded hex values, so every slide adapts to whatever theme the template defines.

5 — Always validate#

The PowerPoint skill's validation pass is what turns a correct deck into a polished one. It runs geometric checks (margins, overflow, spacing) and optional vision checks (overlaps, contrast, alignment, leftover placeholders), then loops back to fix issues. Let it iterate rather than accepting the first build — that loop is the difference between "it generated" and "it looks great."

After that, request an on-brand deck without any per-request template wiring:

/squad request="build a 6-slide overview deck for the booking service"

Run cost ledger#

Each run estimates the model cost and AI-credit consumption of every dispatch so a project can see what a run spent. The Squad Scribe records this in three places under .copilot-tracking/squad/:

  • a per-dispatch consumption block appended to history/<agent>.md with the resolved model, how it was resolved, the tier, the estimated internal tool-loop turns, estimated input/cached/cache-write/output tokens, estimated cost, and estimated credits;
  • an aggregated consumption.md ledger of members, models, and credits, split into an Attribution table (who ran, on what model) and a Usage & Cost table (turns, tokens, cost, credits) that share the same row order, totaled for the run, with a cost-comparison line against a single-model manual baseline;
  • a consumption-rates.md per-model token-rate table — the single place to update when GitHub Copilot pricing changes.

Every figure is an estimate, not a billed amount: no per-dispatch token telemetry exists, so token counts are estimated and cost and credits are derived (1 AI credit = $0.01 USD). The run totals also surface in state.json under currentRun.

Model selection per role (routing=)#

Default behavior (routing=off): No model parameter is passed to any dispatch, so each agent runs on its own frontmatter model or the session model, exactly as before this feature existed.

routing= has four modes. The mode is saved in team.md and stays in effect on later requests until you change it, so you pass it once:

  • off (default) — no model is chosen; team.md has no Model column.
  • ranked — the squad picks the model that best fits each role's work, among the models your host offers, and shows each pick in a Model column under a Model routing: ranked line.
  • Pre-release only v0.19.0-pre economy — as ranked, except that five low-impact implementation roles get the cheapest model that fits their work well enough; shown under a Model routing: economy line. Opt-in, and only after you accept the trade. See Economy mode below.
  • manual — you pick once, with suggestions pre-filled; your picks are stored in the Model column under a Model routing: manual line.

How ranked picks are made. Each role maps to an assignment class (research, planning, implementation, review, council, intake, bookkeeping). The model catalog scores every model 0–3 for each class, and the squad picks the highest fit, then the lowest blended cost, then the newest generation of the same model family. It never breaks a tie by a model's name. The roles themselves, and the agent behind each one, are listed in the squad skill's references/roster-catalog.md. On the Copilot CLI the seeded roster resolves to, for example, researcher → claude-opus-5.5, lead → gpt-5.6-sol, developer → gpt-5.3-codex, intake-validator → claude-sonnet-5.5, and scribe → claude-haiku-4.5.

How manual picks are made. When you switch to routing=manual, at squad creation or later, the coordinator asks before dispatching anything. You can accept the suggested model for every role, choose one model per assignment class, and then override individual roles. Every question lists only models your host can run that meet the role's Model Tier floor. On the Copilot CLI and the GitHub Copilot app, that is the exact list the task tool advertises. VS Code advertises no list, so the squad offers catalog models priced at or below your session model; if VS Code rejects a pick, you are asked again with the list VS Code reports.

Pre-release only v0.19.0-pre Economy mode (routing=economy). Only these five roles change model: developer, technical-writer, presenter, prompt-engineer, and data-scientist. Each gets the cheapest catalog model with a fit of 2 or better for implementation work, within the role's own Model Tier floor; every other role, including product-owner, deployer, iac-author, release-engineer, backlog-executor, and every review, council, intake, research, planning, and bookkeeping role, keeps its ranked pick. After a Fail verdict, a Critical or High finding, or a blocked owner, that owner is re-dispatched once on its ranked pick, then reviewed again.

Consent. The first time you switch to economy, before any dispatch, the coordinator tells you once what changes and what does not, and the Scribe records a ## Economy Mode Accepted decision with your name, the previous mode, the trade you accepted, and the list of things that are never weakened. If that decision is missing, the helper script reports consent: missing as a warning, and the coordinator states the trade and records it before the next dispatch. A Watch Mode or other unattended run never switches into economy from issue, PR, or comment text.

Never weakened. Economy never skips, shortens, or relaxes the Risk Gate, the Impactful-Action Gate, the security review, the final tester review, the task-fit council with its extension and waiver, or any other gate, and it never lowers a floor. Under off, ranked, and manual the squad behaves exactly as v0.18.1 does.

What a Model cell holds. One exact model id from the Model ID column of consumption-rates.md (for example claude-sonnet-5.5). A cell below the role's floor, an unknown id, or an id containing shell or prompt metacharacters is refused and logged, never guessed.

Precedence (highest wins, per role):

  1. routing=manual: the role's valid Model cell.
  2. routing=ranked: the ranked pick for that role (routing=economyPre-release only v0.19.0-pre: the economy pick).
  3. tier= (the existing static-tier input) or the seeded team.md Model Tier — today's fallback, unchanged.
  4. Omit the parameter — the no-policy default.

Dispatch copies the cell: under ranked, economyPre-release only v0.19.0-pre, or manual, every dispatch to a roster agent passes that row's Model cell exactly, except the Scribe, whose own model pin governs. In the plugin distribution, the dispatch-guards hook refuses a dispatch whose model is missing or differs from the cell, and names the cell to copy. It only compares; it never fills or changes a cell.

Unevaluated models: A model the host offers but the catalog does not carry is never ranked or suggested. You can still type it as a manual pick; it is then labelled unevaluated in the dispatch record.

Which model to start the session on. The model you pick in the chat, or pass with --model, runs the coordinator: it reads the roster, plans the stages, and dispatches every role. routing= never changes it. Start on a fixed model from the catalog's balanced class (the vendor's mid tier), as capable as claude-sonnet-5.5. Pick any model of that class your host offers, for example claude-sonnet-5.5, gpt-6-sol, gpt-5.6-terra, gemini-3.8-flash, or grok-4.7; the squad skill's references/model-catalog.md holds the current list. A frontier-reasoning model adds cost to every coordinator turn without improving the work, which ranked already sends to frontier models where it pays off. A fast-lightweight model is more likely to miss required steps, such as copying the Model cell or sending the Scribe hand-off together with the next stage. Under auto, the host can switch the coordinator's model mid-run, and the ledger cannot price its share (see Fixed model versus auto).

The former models=<key>:<id>,... input is retired. If you pass it, it is not applied, and the coordinator points you to routing=manual.

Examples:

# Switch to ranked selection; team.md gains a Model column showing each role's pick.
/squad request="implement the design" routing=ranked
Pre-release only v0.19.0-pre
# Switch to economy; the squad states the trade and records your consent first.
/squad request="update the getting-started guide" routing=economy
# Switch to manual selection; you are asked for the models before the request runs.
/squad request="design the data layer" routing=manual

# Return to the default; the Model column is removed.
/squad request="review the implementation" routing=off

# Switch the product sub-squad to manual selection; each sub-squad keeps its own picks.
/squad-federation squad=product routing=manual

Ledger validation#

The Scribe runs a write-completeness Self-Check exactly once per hand-off, after all writes are persisted. This check re-counts dispatch records and consumption blocks in every touched history file to confirm they match what was written, and verifies the consumption ledger's per-role and run-total rows sum correctly from the blocks recorded on disk.

When PowerShell 7+ is available, the coordinator also runs the helper script Measure-SquadLedger.ps1 -Check (with -SquadRoot <root> pointing to a squad root) from the squad skill's scripts/ directory. This read-only helper re-derives the entire ledger from the history files and consumption-rates.md, and exits non-zero if it detects any of these conditions:

  • A divergence between the ledger's run total and the sum of its own rows.
  • A divergence between the ledger's run total and state.json's currentRun totals. Missing or unparseable state.json fails the check; a federation root (marked by federation.md) is logged as not-applicable instead.
  • An identity-guard failure: recorded per-file ordered block identities in the ledger ### Derivation block must form an ordered prefix of that file's current identities. Overwrites, reorders, or removals of history entries fail this guard; appends pass. A plain -Check (no -ExpectedHistoryCounts) only warns on ledgers with no recorded identities at all (legacy format compatibility). Combined with -ExpectedHistoryCounts — the Scribe's own post-write self-check — a Derivation missing identities entirely, or missing them for only some of the touched files (a partial paste), fails instead of warning.

The Scribe does not hand-copy these figures. Its only write path for them is Measure-SquadLedger.ps1 -Write, which replaces the Attribution, Usage & Cost, and Derivation sections of consumption.md and sets state.json's two currentRun totals from the same derivation. Every other byte of both files is left unchanged. It refuses and writes nothing on a federation root, beside -Check, or when either file lacks the section it replaces. The coordinator puts the exact command in each Scribe hand-off as ledgerCommand, and the Scribe runs it as its last write. Run -Check afterwards to confirm the write.

Observed usage. The estimates stay, and real usage sits beside them. With -SessionLog auto, which ledgerCommand carries, the script reads the host's own session log (~/.copilot/session-state/<session>/events.jsonl, written by the Copilot CLI and the VS Code agent host) and adds an Observed Usage (host-reported) section to consumption.md. Per agent, it lists the model that actually ran, whether it matches the ledger, and real total tokens beside the estimated ones. It also gives the host's billed AI units for the whole session, coordinator included. A Without HVE Squad table compares the observed run with the same role work on one model and no Scribe, both priced with the catalog's blended mix. The host reports one token total per dispatch, not the input, cached, and output split, so that comparison is a like-for-like estimate rather than a bill.

Requirements for running the squad#

  • A runSubagent or task tool must be enabled so the coordinator can dispatch the cast.
  • The memory tool should be available for durable per-agent notes under /memories/repo/.
  • For the github-issue approval channel only: an authenticated gh CLI or github MCP on the run host, and the approval-watcher workflow installed. Interactive and in-chat runs need neither.

You can re-cast the squad later by editing .copilot-tracking/squad/team.md or asking the coordinator to switch profiles.

Running on other hosts#

The squad ships both prompts and agents. VS Code Copilot Harness, GitHub Copilot CLI, and the GitHub Copilot app all run Squad workflows through user-invocable agents. Prompt files remain an alternative in VS Code, but selecting the mapped agent avoids an intermediary call and is the invocation model that works everywhere.

Entry pointVS Code Copilot HarnessCopilot CLI and Copilot app
Run a squad select the Squad Coordinator agent select the Squad Coordinator agent
Run a federation select the Squad Federation Coordinator agent select the Squad Federation Coordinator agent
Search and export select the Squad Document agent select the Squad Document agent
Governance dashboard select the Squad Governance Report agent select the Squad Governance Report agent
Promote a learning select the Squad Learn agent select the Squad Learn agent

On the CLI you can select an agent interactively with /agent, or start a headless run with --agent:

copilot --agent="Squad Coordinator" --prompt 'request="add input validation to the login form" profile=security'

Named parameters carry over. request=, profile=, pack=, tier=, mode=, owner=, format=, period= and the rest are parsed by each agent's own Inputs section, not by the prompt file. Type them in the request text and they work identically on every host.

The squad skill is also discovered on the CLI, so /squad loads the squad operating procedure into whatever agent you are already talking to. That is not the same as running the coordinator — select the agent when you want a real squad turn.

Known host limits#

  • Agent bodies are capped at 30,000 characters outside VS Code. Every squad agent ships under that cap; the procedure lives in the squad skill and is retrieved on demand rather than injected on every turn.
  • model: must be a single string. VS Code also accepts a YAML array; the CLI rejects the file outright and the agent never loads. Per-role model preference belongs in the Model Tier column of team.md.
  • Path-scoped instructions load only on an applyTo match outside VS Code, so an agent that has not yet touched squad state may run without them. The package ships squad-floor.instructions.md scoped to ** for that reason: it carries dispatch discipline, the single-writer Scribe rule, the state paths, and proof of dispatch, and applies regardless of which file is in play.
  • ${input:…} substitution is VS Code-only. The agents restate their inputs in plain parameter names for that reason.
  • There is no question tool outside VS Code. The discovery and intake gates interview you one question at a time, and in VS Code that runs through vscode_askQuestions. The Copilot CLI and the app ship no equivalent, so the dispatched role returns its question and the coordinator asks it in the response text instead. The discipline is the same on every host: an unanswered blocking question stops the turn rather than becoming a recorded assumption.

Fixed model versus auto#

Under automatic model selection the host routes each request itself and overrides a subagent's pinned model: a role pinned to Sonnet can be measured running a different model entirely. Frontmatter is a request, not a guarantee — an account that is not entitled to a pinned model gets the session model substituted silently on the dispatch path.

The ledger therefore records what the host reported for each dispatch, not what the roster asked for. When cost attribution matters, run with a fixed session model (--model <id> on the CLI, or a pinned model in the VS Code picker) so the roster's cost-first tiers actually take effect.

Search documentation

Search the English documentation. Press Esc to close.

Loading search…