From a15f2e2be8e8b9aa4f01a74f016c17c6051b5c3d Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Tue, 1 Sep 2026 10:28:55 -0700 Subject: [PATCH 1/4] docs(gh-aw): correct credentials guidance and document activation fixes MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The bootstrap procedure listed SQUAD_GITHUB_APP_PRIVATE_KEY and SQUAD_GITHUB_TOKEN as a setup-time item with no statement that they need not exist. The clarification sat ~95 lines downstream in an "Optional:" section a reader following the numbered path never reaches before deciding whether they are blocked. Two independent agents read that passage and concluded a PAT was a prerequisite for enlisting a fresh repo. It is not. The correction now lands inline at the point of misreading, and is mirrored byte-identically into the three gh-aw-enlistment SKILL.md copies (outside the bounded allowlist block). Also documents four merged activation fixes that shipped with zero docs changes, traceable to workflows/squad.md on dev: - #1959 label auto-provisioning (squad.md:113-115, 1307, 1931-1945, 2004) — add-labels create-if-missing auto-creates squad/squad:{agent}; auto-provisioned labels get a deterministic color and empty description, which is expected and not a failure. - #1961 bounded caps (squad.md:111, 121, 1997, 1999) — create-issue 75, add_labels 110; the two shortfall paths are kept distinct; report_incomplete does NOT fail the run, so the durable signal is the [aw] ... reported incomplete result tracking issue, not the run conclusion. A cap is named only when observed. - #1963 accepted-vs-applied (squad.md:1392, 2058-2081) — defines accepted, states what a summary must not claim, and explains why the distinction exists (create-issue labels: silently drops missing names). - #1962 temporary IDs — documented only where user-observable: shortfall reports identify items by #aw_epic{K}/#aw_task{N}/#aw_wi{N}. Adds the Activation bindings: JSON block as the checkable verification surface, and updates the stale troubleshooting row that predated #1961. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .squad/skills/gh-aw-enlistment/SKILL.md | 8 ++ docs/src/content/docs/guide/gh-aw.md | 121 +++++++++++++++++- .../skills/gh-aw-enlistment/SKILL.md | 8 ++ .../skills/gh-aw-enlistment/SKILL.md | 8 ++ 4 files changed, 143 insertions(+), 2 deletions(-) diff --git a/.squad/skills/gh-aw-enlistment/SKILL.md b/.squad/skills/gh-aw-enlistment/SKILL.md index 6d67daa7b..4feb92277 100644 --- a/.squad/skills/gh-aw-enlistment/SKILL.md +++ b/.squad/skills/gh-aw-enlistment/SKILL.md @@ -129,6 +129,14 @@ On a clean repo, `gh aw add` reports these expected safe updates and **nothing e - Action: **`bradygaster/squad/.github/actions/squad-init`** +> **These are referenced names, not prerequisites.** `gh aw add` lists the secrets +> the workflows *reference* so you can approve that surface — it is not asking you +> to supply them. Both secrets are optional, they need not exist, and neither is +> required to enlist a repository. Single-repo activation runs on the built-in +> `github.token`. Configure them only for cross-repo access or elevated +> permissions. Auth precedence: GitHub App token, then the PAT, then +> `github.token`. Never block an enlistment waiting for a credential. + If — and only if — the report contains exactly those documented entries, complete the one-time approval: diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index d6f96f524..29a385a40 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -64,6 +64,11 @@ gh pr edit --add-reviewer @copilot gh pr checks --watch ``` +> Step 7 stages `.github/skills/` because `gh aw add` installs the Squad skills +> alongside the workflows, and it deliberately does not stage `.github/aw/logs/`. +> Downloaded workflow logs are local diagnostic output — see [ignoring downloaded +> logs](#open-the-bootstrap-pull-request) before you commit. + After the bootstrap PR is reviewed and merged, open an issue in your repo and write `/squad cast` in the body or a comment. Squad analyzes your codebase, composes a team of specialist agents, and opens a second PR with the result. @@ -134,6 +139,9 @@ The installed top-level workflow set is: - `squad-deps-worker.md` and `squad-deps-worker.lock.yml` - `squad-review.md` and `squad-review.lock.yml` +`gh aw add` also installs the Squad skills under `.github/skills/`, which is why +the bootstrap commit stages that path alongside the workflows. + > **Branch note:** `@dev` pulls from the latest development branch where new modes and fixes land first. Stay on `@dev` to get improvements as they ship. Once gh-aw support reaches stable, you can switch to `@main` or drop the ref entirely for the default branch. This registers the Squad workflow in your repository's agentic workflow @@ -149,6 +157,15 @@ On a clean repository, `gh aw add` reports these expected safe-update changes: - Restricted secrets: `SQUAD_GITHUB_APP_PRIVATE_KEY` and `SQUAD_GITHUB_TOKEN` - Action: `bradygaster/squad/.github/actions/squad-init` +> **These are referenced names, not prerequisites.** `gh aw add` lists the secrets +> the workflows *reference* so you can approve that surface — it is not asking you +> to supply them. Both secrets are optional, they need not exist, and you do not +> need to create either one to enlist a repository. Single-repo activation runs on +> the built-in `github.token`. Configure these only for cross-repo access or +> elevated permissions — see [enhanced permissions with a GitHub +> App](#optional-enhanced-permissions-with-a-github-app) and [PAT +> fallback](#optional-pat-fallback). + Review the report before approving it. If it contains only those documented entries, complete the first-install approval with: > @@ -683,13 +700,111 @@ After this, the plan is ready to activate. /squad plan activate ``` -Creates GitHub issues from the accepted plan with proper labels (`squad`, +Creates GitHub issues from the accepted plan with Squad labels (`squad`, `squad:{agent-name}`), acceptance criteria, dependency references, and phase assignments. Flat plans create one child issue per planned task directly under the originating issue; they do not add a duplicate epic. Dependencies use native `blockedBy` edges when the installed safe-output tool supports them, otherwise they remain explicit `Depends On` references in each issue body. +#### Labels are created automatically + +You do not need to pre-create any label. Activation applies labels through the +`add-labels` safe output, which is configured with `allowed: [squad, "squad:*"]` +and `create-if-missing: true`, so `squad` and each `squad:{agent}` label is +created the first time a run needs it. A fresh repository with zero Squad labels +requires no manual label setup. + +A label created this way receives gh-aw's deterministic color and an **empty +description**. That is expected on a fresh repository, not a failure. Labels that +already exist are left as they are, and re-applying a label on a rerun is a no-op. + +#### "Accepted" in an activation summary does not mean "applied" + +Activation summaries report **accepted operations**, and that word is exact. +Issue creation and labeling are gh-aw *safe outputs*: during the agent's turn the +run can only queue an operation against a target and observe that it was +accepted. gh-aw applies the queued operations afterward, in a separate post-agent +job. Nothing in the run reads labels back from GitHub. + +So a correct summary says a label operation was **accepted**. It must not claim a +label was applied, landed, verified, confirmed, or checked on the issue. + +This vocabulary exists for a concrete reason. Labels do not ride along with issue +creation: `create-issue`'s own `labels:` field cannot create a missing label — +GitHub silently drops label names the repository does not already have instead of +creating them — so it is never evidence that a label landed. Labels therefore +travel as separate `add_labels` calls, and "accepted" is the strongest thing the +run can truthfully say about one. + +Practical consequence: an accepted summary is strong evidence, not proof. To +confirm what actually landed, read the issues themselves: + +```bash +gh issue list --label squad --json number,title,labels +``` + +#### Activation is capped, and shortfalls are reported + +A single activation run is bounded by two safe-output caps: + +| Safe output | Cap | Covers | +|-------------|-----|--------| +| `create-issue` | 75 | Issues created in one run | +| `add-labels` | 110 | Label operations in one run | + +Two different shortfalls are checked separately, and they are not +interchangeable — the trigger, the wording, and the remedy differ: + +| Shortfall | Trigger | What the report says | +|-----------|---------|----------------------| +| Issues not created | Created count is below the plan's declared total | `N of M issues created so far — rerun the identical activation command to continue.` | +| Labels not applied | An activated issue had no `add_labels` call accepted | `{labeled} of {activated} activated issues had a label operation accepted` | + +Either one calls `report_incomplete`. **This does not fail the run.** The workflow +run still concludes `success`, so `gh run view --json conclusion` is not a way to +detect a truncated activation. The durable, user-visible signal is a tracking +issue in your repository titled `[aw] ... reported incomplete result`, which +gh-aw opens or updates: + +```bash +gh issue list --search '"reported incomplete result" in:title' --state all +``` + +If a cap was actually reached, the report names which cap and lists the work +items that did not fit, and recommends `/squad plan activate phase {N}` to +continue in smaller batches. A cap is named only when it was *observed* — the +workflow forbids offering a cap as a guessed explanation, so an incomplete report +will not always attribute the shortfall to one. + +Work items created in the same run are identified in that report by the temporary +IDs the run minted (`#aw_epic{K}`, `#aw_task{N}`, `#aw_wi{N}`) rather than by +issue number, because at that point creation is still deferred and no real number +exists yet. + +Do not read a green run as a complete activation. Check for that tracking issue. + +#### Verifying an activation: the bindings block + +Every phase and full activation artifact includes an `Activation bindings:` +fenced JSON block — one entry per created or recognized task, built only from +accepted operations. This is the most directly checkable surface Squad emits: a +deterministic post-activation checker compares those bindings against the labels +actually present on the issues. + +You can do the same check by hand — read the bindings out of the activation +comment, then compare them against reality: + +```bash +gh issue list --label squad --json number,title,labels +``` + +Where an owner did not become a `squad:{agent}` label — a multi-owner epic, or an +owner matching no roster name — the summary carries a required `Non-roster agent +values` heading naming the value and the issue, and the matching binding records +an omission reason. An omission is always reported explicitly, never left for you +to infer. + ### Incremental phase acceptance Instead of accepting an entire plan at once, you can accept and activate one @@ -1186,7 +1301,9 @@ can leave the installed sources at a different revision than the SHA you intend. | `/squad` command is ignored | Lock file not committed or workflow not compiled | Run `gh aw compile --strict`, commit the lock file, and push | | Universe is full on cast-member | All character names in the universe are allocated | Retire an unused member first, or re-cast with `/squad cast` | | "No plan found" on plan accept | No `/squad plan` comment exists yet | Run `/squad plan` first to generate a plan for review | -| Plan activation creates fewer issues than the accepted plan declares | The run ended before every missing issue was created | Re-run the identical activation command — title matching resumes without duplicating existing issues | +| Plan activation creates fewer issues than the accepted plan declares | The run ended early, or it reached the `create-issue` (75) or `add-labels` (110) safe-output cap | Look for an `[aw] ... reported incomplete result` tracking issue — it names the shortfall and, when a cap was reached, which cap and what did not fit. Re-run the identical activation command (title matching resumes without duplicating existing issues), or activate one phase at a time with `/squad plan activate phase {N}` | +| Activation run is green but some issues are missing or unlabeled | `report_incomplete` records truncation without failing the run | A green run is not proof of a complete activation. Check for the `[aw] ... reported incomplete result` tracking issue, then verify with `gh issue list --label squad` | +| A Squad label has no description and an unexpected color | It was auto-created on a fresh repo by `create-if-missing` | Expected, not a failure. Edit the label if you want a description or a specific color | | `/squad implement` cannot create a PR | Actions is not allowed to create pull requests | Enable **Allow GitHub Actions to create and approve pull requests** in repository Actions settings | | Epic implementation dispatches no workers | Every child is blocked or already has an open implementation PR | Merge dependency PRs, then run `/squad implement` on the epic again | | Standalone activation fails before init | `SQUAD_CLI_VERSION` is invalid or its release assets are unavailable | Correct the variable or select a published release, then use **Re-run failed jobs** | diff --git a/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md b/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md index 6d67daa7b..4feb92277 100644 --- a/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md +++ b/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md @@ -129,6 +129,14 @@ On a clean repo, `gh aw add` reports these expected safe updates and **nothing e - Action: **`bradygaster/squad/.github/actions/squad-init`** +> **These are referenced names, not prerequisites.** `gh aw add` lists the secrets +> the workflows *reference* so you can approve that surface — it is not asking you +> to supply them. Both secrets are optional, they need not exist, and neither is +> required to enlist a repository. Single-repo activation runs on the built-in +> `github.token`. Configure them only for cross-repo access or elevated +> permissions. Auth precedence: GitHub App token, then the PAT, then +> `github.token`. Never block an enlistment waiting for a credential. + If — and only if — the report contains exactly those documented entries, complete the one-time approval: diff --git a/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md b/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md index 6d67daa7b..4feb92277 100644 --- a/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md +++ b/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md @@ -129,6 +129,14 @@ On a clean repo, `gh aw add` reports these expected safe updates and **nothing e - Action: **`bradygaster/squad/.github/actions/squad-init`** +> **These are referenced names, not prerequisites.** `gh aw add` lists the secrets +> the workflows *reference* so you can approve that surface — it is not asking you +> to supply them. Both secrets are optional, they need not exist, and neither is +> required to enlist a repository. Single-repo activation runs on the built-in +> `github.token`. Configure them only for cross-repo access or elevated +> permissions. Auth precedence: GitHub App token, then the PAT, then +> `github.token`. Never block an enlistment waiting for a credential. + If — and only if — the report contains exactly those documented entries, complete the one-time approval: From 22ba74ff37815e42eb431fb7011c2a7a5518408d Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Tue, 1 Sep 2026 10:32:13 -0700 Subject: [PATCH 2/4] chore: add changeset for gh-aw-enlistment skill template change MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The changelog gate's SDK_CLI_PATH_REGEX (squad-ci.yml:273) matches ^packages/squad-(sdk|cli)/templates/, not just src/ — template edits ship as scaffolding and are covered deliberately. Both packages distribute the gh-aw-enlistment skill, so both take a patch bump. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .changeset/1973-gh-aw-enlistment-credentials.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/1973-gh-aw-enlistment-credentials.md diff --git a/.changeset/1973-gh-aw-enlistment-credentials.md b/.changeset/1973-gh-aw-enlistment-credentials.md new file mode 100644 index 000000000..0ea4b6351 --- /dev/null +++ b/.changeset/1973-gh-aw-enlistment-credentials.md @@ -0,0 +1,6 @@ +--- +"@bradygaster/squad-cli": patch +"@bradygaster/squad-sdk": patch +--- + +Correct the `gh-aw-enlistment` skill's first-install guidance: `SQUAD_GITHUB_APP_PRIVATE_KEY` and `SQUAD_GITHUB_TOKEN` are names `gh aw add` reports as *referenced* for approval, not prerequisites. Neither secret needs to exist, and single-repo activation runs on the built-in `github.token`. The scaffolded skill previously listed them as a bare setup-time item, which led readers to conclude a PAT was required to enlist a repository. From e37ffce88c901777457ea1e6a990d2793cbd78d6 Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Tue, 1 Sep 2026 10:34:43 -0700 Subject: [PATCH 3/4] docs(gh-aw): correct activation capacity and rescope label-evidence claim MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Addresses review findings A-D on the activation section. A. The cap table presented 75 as "issues created in one run", which would lead a reader to size for 75. squad.md:105-107 states the actual ceiling is 50 issues per activation run; 75 is 50 worst-case plus 25 bounded margin, and 110 covers both readings of the add-labels worst case (50 calls / 100 label names). Now states the 50-issue ceiling as the user-facing number and presents 75/110 as underlying headroom, preserving the workflow's statement that `max` counts safe-output items (tool calls), not label names. B. Rescoped the label-evidence claim to the workflow's own epistemic scope (squad.md:2059-2060): `create-issue`'s `labels:` field never lands a label the activation run can claim. Dropped the generalized assertion about GitHub API behavior. Note: "silently drops names the repository lacks" is verbatim shipped prose at squad.md:2060 — the scoping concern is upstream in the workflow, flagged rather than propagated here. C. Added the fast-path phase temporary ID `#aw_ph{N}` (squad.md:1289), which was missing from the documented identifier set. D. Listing labels proves a label exists, not that it landed on the right issue. Added a per-issue verification path: read the Activation bindings: block from the origin issue's comments, then compare each binding against `gh issue view {issue} --json title,labels`. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/src/content/docs/guide/gh-aw.md | 49 +++++++++++++++++++--------- 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 29a385a40..0440cfa66 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -731,11 +731,11 @@ So a correct summary says a label operation was **accepted**. It must not claim label was applied, landed, verified, confirmed, or checked on the issue. This vocabulary exists for a concrete reason. Labels do not ride along with issue -creation: `create-issue`'s own `labels:` field cannot create a missing label — -GitHub silently drops label names the repository does not already have instead of -creating them — so it is never evidence that a label landed. Labels therefore -travel as separate `add_labels` calls, and "accepted" is the strongest thing the -run can truthfully say about one. +creation: a label reaches an activated issue through exactly one route, an +accepted `add_labels` operation targeting that issue. `create-issue`'s own +`labels:` field never lands a label the activation run can claim, so it is never +evidence that a label arrived. Labels therefore travel as separate `add_labels` +calls, and "accepted" is the strongest thing the run can truthfully say about one. Practical consequence: an accepted summary is strong evidence, not proof. To confirm what actually landed, read the issues themselves: @@ -746,12 +746,19 @@ gh issue list --label squad --json number,title,labels #### Activation is capped, and shortfalls are reported -A single activation run is bounded by two safe-output caps: +A single activation run is bounded. **The user-facing ceiling is 50 issues per +activation run.** Plan for that number. -| Safe output | Cap | Covers | -|-------------|-----|--------| -| `create-issue` | 75 | Issues created in one run | -| `add-labels` | 110 | Label operations in one run | +The two underlying safe-output caps are set above that ceiling on purpose, so +they are headroom rather than the limit you should size against: + +| Safe output | Cap | Derivation | +|-------------|-----|------------| +| `create-issue` | 75 | 50 worst-case issues plus 25 bounded margin | +| `add-labels` | 110 | Covers both readings of the worst case — 50 calls (one per issue) and 100 label names (two each) | + +`max` counts safe-output **items (tool calls)**, not label names, and it is +enforced at invocation and collection — neither enforcement fails the run. Two different shortfalls are checked separately, and they are not interchangeable — the trigger, the wording, and the remedy differ: @@ -778,9 +785,10 @@ workflow forbids offering a cap as a guessed explanation, so an incomplete repor will not always attribute the shortfall to one. Work items created in the same run are identified in that report by the temporary -IDs the run minted (`#aw_epic{K}`, `#aw_task{N}`, `#aw_wi{N}`) rather than by -issue number, because at that point creation is still deferred and no real number -exists yet. +IDs the run minted — `#aw_epic{K}` and `#aw_task{N}` on the hierarchical path, +`#aw_ph{N}` for a fast-path phase issue and `#aw_wi{N}` for a fast-path work item +— rather than by issue number, because at that point creation is still deferred +and no real number exists yet. Do not read a green run as a complete activation. Check for that tracking issue. @@ -792,13 +800,24 @@ accepted operations. This is the most directly checkable surface Squad emits: a deterministic post-activation checker compares those bindings against the labels actually present on the issues. -You can do the same check by hand — read the bindings out of the activation -comment, then compare them against reality: +You can do the same check by hand. Listing labels proves a label exists somewhere, +but not that it landed on the *right* issue — so read the bindings out of the +activation comment and compare them per issue: ```bash +# 1. Find the Activation bindings: block on the issue you activated +gh issue view {origin-issue} --json comments --jq '.comments[].body' + +# 2. For each binding, compare its recorded issue and label against reality +gh issue view {issue} --json title,labels + +# Broad sweep: every Squad-labeled issue at once gh issue list --label squad --json number,title,labels ``` +A binding whose `label` does not match the labels actually on that issue is the +discrepancy the checker exists to catch. + Where an owner did not become a `squad:{agent}` label — a multi-owner epic, or an owner matching no roster name — the summary carries a required `Non-roster agent values` heading naming the value and the issue, and the matching binding records From e4e2bfd72dc3f4c92f3b6f8c16e31c337e9127b0 Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Tue, 1 Sep 2026 10:39:56 -0700 Subject: [PATCH 4/4] docs(gh-aw): explain add-labels vs add_labels naming surfaces Review flagged the two spellings as inconsistent. Audited every occurrence: all six are already correct for their surface. The hyphenated add-labels is the safe-outputs configuration key (squad.md:113) and is what the caps apply to; the underscored add_labels is the run-time tool call (squad.md:1294) and is what appears in summaries and incomplete reports. Rather than collapse them to one spelling, which would make one of the two surfaces unsearchable, this states the distinction explicitly at first joint mention. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- docs/src/content/docs/guide/gh-aw.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 0440cfa66..61c8ed2b8 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -715,6 +715,13 @@ and `create-if-missing: true`, so `squad` and each `squad:{agent}` label is created the first time a run needs it. A fresh repository with zero Squad labels requires no manual label setup. +> **Two names, one operation.** `add-labels` (hyphenated) is the *configuration +> key* in the workflow's `safe-outputs` block — that is the spelling to search for +> in `squad.md` and the one the caps below apply to. `add_labels` (underscored) is +> the *tool call* the agent makes at run time, and it is the spelling that appears +> in activation summaries and incomplete reports. They refer to the same +> operation; this page uses whichever form matches the surface being described. + A label created this way receives gh-aw's deterministic color and an **empty description**. That is expected on a fresh repository, not a failure. Labels that already exist are left as they are, and re-applying a label on a rerun is a no-op.