Invoke the coordinator
/squad request="add input validation to the login form"
Two entries named squad? The / picker lists
both prompts and skills, and the package ships one of each. Pick the
prompt — described as "Hands a request to the Squad Coordinator…" —
to actually run the squad. The skill — "Operating procedure for the HVE
Core Squad Coordinator…" — only loads the squad procedure into whatever agent you are
already talking to; the coordinator and its subagents load it on their own, so you rarely
need to select it yourself.
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, orpack=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. -
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 inteam.mdshare the sameRole(for exampleowner=Betawhen the roster has twodeveloperrows). -
mode=autonomous|autopilot— the autonomy mode for this turn. Omit it to run interactively, approving each step.
/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
/squad entry point.
Autonomy modes
How much the squad does before it asks you:
| Mode | How to run it | Who 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).
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
productorfull— those are the only profiles that seedanalyst, 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
| Depth | Roles dispatched, in order | Produces | Use 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:
-
Authenticate GitHub on the run host. Either run
gh auth login(theghCLI is sufficient on a headless VM) or configure the officialgithubMCP server. The package ships a reference entry in.github/skills/squad/mcp.template.jsonyou can merge into your.vscode/mcp.json; the GitHub MCP is preferred when present, and the squad falls back togh, then to in-chat. The token needsrepo+issuesscope. -
Install the approval watcher. Copy the reference workflow
.github/skills/squad/github-approval-watcher.workflow.ymlto.github/workflows/squad-approval-watcher.ymlin the repo that hosts your approval issues, then commit it. It relays your/approve,/approve-all,/changes:, or/stopreply back so the run resumes — and only an authorized handle's recognized keyword acts (free-form comment text is never executed as a command). -
Pick
github-issueat build time and give the coordinator the GitHub handle to @mention and theowner/repofor 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.
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)
-
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. - Protect your default branch. Require a pull request and review before merge, so the squad's draft PR can never merge itself.
-
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: writepermission 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.) -
Install the trigger workflow. Copy the reference workflow
.github/skills/squad/squad-watch.workflow.ymlto.github/workflows/squad-watch.yml, review it, and commit it. -
Install the approval watcher (if you have not already) so gate approvals
flow back: copy
.github/skills/squad/github-approval-watcher.workflow.ymlto.github/workflows/squad-approval-watcher.yml. -
Label an issue
squad/autoto 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.
| Trigger | How it fires | What the squad does | Shipped? |
|---|---|---|---|
| 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 has | What 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 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
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:
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"
/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.
/squad-federation promote 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 just ask on /squad and accept the handoff it offers)
/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, /squad-federation init (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 —
/squad-federation squad=azure mode=autopilot request="…" runs that one sub-squad's
full pipeline (forward-only, exactly as before). Drop the squad= target and
/squad-federation mode=autopilot request="…" now runs a 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, and ends with a single consolidated final-outcome validation. Each
sub-squad's inner pipeline is unchanged, and it never auto-releases.
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 tomd). Falls back to Markdown when the requested format's tooling is unavailable.outputPath=<path>— where to save the file. Defaults todocs/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 todocs/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 toall).
Dashboard sections
The generated report contains seven sections:
- Governance Gates — council verdicts, intake checks, human gates, and escalation counts.
- Council Verdicts — verdict distribution (Go / Go-With-Conditions / Stop) with findings by role.
- Cost Breakdown — estimated cost by role and model tier.
- Role Dispatch Activity — dispatch counts, models used, success rate, and autonomy tier distribution.
- Risk & Compliance — artifact evidence, test verification, impactful-action gating, and open escalations.
- Activity Timeline — chronological view of dispatches and decisions.
- 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.
/squad-governance-report.
Profiles
The cast each profile seeds:
| Profile | Members | Use when |
|---|---|---|
default | researcher, lead, developer, tester, scribe | General-purpose work; recommended starting point |
full | every role in the cast except the opt-in roles and the four unbacked ones | Complex, cross-cutting projects |
security | researcher, lead, developer, tester, security, supply-chain, rai, privacy, fact-checker, scribe | Security, supply-chain, privacy, threat-modeling, and responsible-AI focus |
design | researcher, lead, developer, tester, designer, accessibility, scribe | UX/UI and product-design focus |
accessibility | researcher, lead, developer, tester, accessibility, designer, scribe | Accessibility conformance as the goal itself — WCAG 2.2, Section 508, or EN 301 549 assessment and remediation |
architecture | researcher, lead, developer, tester, architect, azure-architect, cost-manager, scribe | System design and architecture focus |
azure | researcher, lead, developer, tester, azure-architect, iac-author, deployer, asbuilt-author, azure-diagnose, architect, cost-manager, security, modernizer, scribe | Azure build with IaC authoring, deployment, post-deploy documentation, troubleshooting, budget, and security oversight |
modernization | researcher, lead, developer, tester, modernizer, architect, azure-architect, iac-author, cost-manager, asbuilt-author, scribe | Legacy uplift — framework and dependency upgrades, re-platforming, SQL or cloud migration |
compliance | researcher, lead, developer, tester, security, supply-chain, vuln-manager, privacy, rai, accessibility, risk-manager, scribe | Conformance evidence is the goal — an audit, an attestation, or a customer security questionnaire |
operations | researcher, lead, developer, tester, azure-diagnose, performance, observability, asbuilt-author, iac-author, deployer, scribe | Running a deployed system — incidents, reliability targets, instrumentation design, and as-built documentation |
product | researcher, lead, developer, tester, analyst, designer, product-owner, presenter, technical-writer, experimenter, data-scientist, intake-validator, scribe | Business 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.
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.
| Pack | Adds | Use when |
|---|---|---|
power-platform | pp-architect, pp-connector | The project is built on Power Platform — Power Apps, Power Automate, Dataverse, Power Pages, or Copilot Studio |
m365-copilot | m365-agent-architect, m365-agent-integrator | The project is built on Microsoft 365 Copilot — declarative agents, TypeSpec agent definitions, API plugins, MCP-backed agents, or Microsoft Graph integration |
aws | aws-architect, aws-diagnose | The 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 doing | Command |
|---|---|
| Greenfield Power Platform app | profile=default pack=power-platform |
| Power Platform app that has to produce audit evidence | profile=compliance pack=power-platform |
| Designing an AWS workload before anything is built | profile=architecture pack=aws |
| One estate spanning Azure and AWS | profile=azure pack=aws |
| On call for a live AWS workload | profile=operations pack=aws |
| An M365 Copilot agent that handles personal data | profile=security pack=m365-copilot |
| A Power Platform solution fronted by an M365 Copilot agent | profile=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 you: /squad request="merge the squad MCP
template into my 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.
- Ask. With a planned backlog in hand, ask the squad to create the items (for example,
/squad request="create these work items in Azure DevOps"). - 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. - 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.
- 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.
- 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
developerrole 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
developerandarchitectroles 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, andSection Header. -
Theme colors and fonts defined in the theme
(Slide Master → Colors / Fonts) so
@theme_namereferences 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, a request as simple as
/squad request="build a 6-slide overview deck for the booking service" produces an
on-brand deck without any per-request template wiring.
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>.mdwith 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.mdledger 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.mdper-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.
Requirements for running the squad
- A
runSubagentortasktool 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-issueapproval channel only: an authenticatedghCLI orgithubMCP 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. Prompt files are a VS Code feature — GitHub Copilot CLI and the GitHub Copilot app never read them. Every squad entry point therefore also exists as an agent, and selecting the agent is the one invocation model that works everywhere.
| Entry point | VS Code | Copilot CLI and Copilot app |
|---|---|---|
| Run a squad | /squad request="…" |
select the Squad Coordinator agent |
| Run a federation | /squad-federation request="…" |
select the Squad Federation Coordinator agent |
| Search and export | /squad-document request="…" |
select the Squad Document agent |
| Governance dashboard | /squad-governance-report |
select the Squad Governance Report agent |
| Promote a learning | /squad-learn |
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
squadskill 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 theModel Tiercolumn ofteam.md. -
Path-scoped instructions load only on an
applyTomatch outside VS Code, so an agent that has not yet touched squad state may run without them. The package shipssquad-floor.instructions.mdscoped 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.