Skip to content

Commit f67bee5

Browse files
bradygasterCopilot
andauthored
fix(gh-aw): preserve ownership staging with bounded index verification (#2116)
* fix(gh-aw): verify ownership metadata in staged installs Handoff for independent revision: staged-tree enumeration still requires the reviewer-requested large-consumer correction before PR creation. Closes #2113 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * fix(gh-aw): bound staged install queries to required paths Independently revise the rejected ownership staging handoff. Avoid recursive consumer-tree enumeration and preserve exact staged type and digest checks. Cover 20,000 unrelated tracked files, unchanged staging, bounded blob reads, index locks, and substituted directories. Closes #2113 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> * docs(changeset): record verified gh-aw ownership staging Add the coordinator-authorized patch changeset for both template-shipping packages to satisfy the hosted changelog gate. Closes #2113 Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent 26c51f0 commit f67bee5

16 files changed

Lines changed: 423 additions & 31 deletions

File tree

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
"@bradygaster/squad-cli": patch
3+
"@bradygaster/squad-sdk": patch
4+
---
5+
6+
Preserve manifest-allowlisted gh-aw ownership metadata through broad consumer ignore rules by force-staging only the exact required ownership file. Verify every required artifact's staged type and bytes before commit or push, using bounded index queries that exclude unrelated consumer files.

‎.squad-templates/skills/gh-aw-enlistment/SKILL.md‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ tools:
1111
when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR."
1212
- name: "gh aw"
1313
description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set."
14-
when: "Installing the immutable native Squad package and compiling its seven workflows into deterministic .lock.yml files."
14+
when: "Installing the immutable native Squad package and compiling its eight workflows into deterministic .lock.yml files."
1515
---
1616

1717
## Context
@@ -146,7 +146,7 @@ gh aw add "bradygaster/squad/workflows@${SQUAD_SHA}"
146146

147147
The nested `workflows/aw.yml` is the only supported distribution registration.
148148
It isolates package auto-discovery from unrelated repository skills and agents,
149-
and installs exactly seven workflows, fifteen runtime resources, and one
149+
and installs exactly eight workflows, seventeen runtime resources, and one
150150
`gh-aw-enlistment` skill at the same resolved revision:
151151

152152
- `squad.md` + `squad.lock.yml`
@@ -156,11 +156,12 @@ and installs exactly seven workflows, fifteen runtime resources, and one
156156
- `squad-retro.md` + `squad-retro.lock.yml`
157157
- `squad-improvement-worker.md` + `squad-improvement-worker.lock.yml`
158158
- `squad-bootstrap.md` + `squad-bootstrap.lock.yml`
159+
- `squad-command-router.md` + `squad-command-router.lock.yml`
159160

160161
`squad-improvement-worker` is part of the standard, coherent install above —
161162
not a separate opt-in add-on. It stays dormant until a maintainer approves a
162163
governance-scoped retrospective proposal (see the gh-aw guide's retrospective
163-
auto-implementation section); installing it alongside the other six keeps the
164+
auto-implementation section); installing it alongside the other seven keeps the
164165
full stack consistent and avoids a second bootstrap pass later.
165166

166167
Report/proposal-only is the default. Ordinary fixes require the explicit
@@ -220,7 +221,7 @@ node .github/workflows/shared/squad-install-verifier.mjs \
220221
This must run after any first-install approval and before committing. Success
221222
criteria:
222223

223-
- All seven workflows compile successfully.
224+
- All eight workflows compile successfully.
224225
- The **only** permitted warning is the known `squad.md` bot-trigger warning: it
225226
configures both slash-command and `github-actions[bot]` triggers, and the bot
226227
trigger is required for controlled worker-continuation dispatches.
@@ -230,7 +231,7 @@ criteria:
230231
### 6. Require the verifier to prove the complete consumer contract
231232

232233
- **STOP** if the verifier reports a missing source/lock pair, missing package
233-
ownership record, stale source/resource digest, incomplete seven-workflow
234+
ownership record, stale source/resource digest, incomplete eight-workflow
234235
registration, or mixed revision.
235236
- Use only the recovery commands printed by the verifier. They reinstall the
236237
complete package at one immutable revision; never repair one workflow or
@@ -258,6 +259,8 @@ Stage **only** the documented generated surfaces, then verify the staged set:
258259

259260
```bash
260261
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
262+
node .github/workflows/shared/squad-install-verifier.mjs \
263+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
261264
git diff --cached --stat
262265
# No deletions should be staged:
263266
test -z "$(git diff --cached --diff-filter=D --name-only)" || { echo "STOP: staged deletions"; exit 1; }
@@ -267,6 +270,15 @@ test -z "$(git diff --cached --diff-filter=D --name-only)" || { echo "STOP: stag
267270
edits to **unrelated files**, or committed **log/diagnostic output**. Re-scope with
268271
explicit `git add -- <path>` — never `git add .`, `git add -A`, or `git commit -a`.
269272

273+
Consumer rules such as `packages/` can silently ignore the required ownership
274+
JSON under `.github/aw/packages/`. The staged verifier force-adds only the exact
275+
native package ownership JSON when it is ignored and untracked. It then verifies
276+
every manifest-required source, lock, runtime, skill, manifest and ownership
277+
file against the validated working-tree bytes in a snapshot of the Git index.
278+
**STOP before commit/push** on missing metadata, a staging failure, an omitted
279+
required file or a staged digest mismatch. Never force-add a directory or glob.
280+
Rerun this gate after changing or restaging any installation file.
281+
270282
### 8. Commit, push, and open the bootstrap PR to the captured default branch
271283

272284
```bash
@@ -360,6 +372,8 @@ node .github/workflows/shared/squad-install-verifier.mjs \
360372
--verify-install --source-revision "${SQUAD_SHA}" --strict-compile
361373

362374
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
375+
node .github/workflows/shared/squad-install-verifier.mjs \
376+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
363377
git commit -m "ci: add Squad agentic workflow"
364378
git push -u origin HEAD
365379
gh pr create --base "${default_branch}" \

‎docs/src/content/docs/guide/gh-aw.md‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ node .github/workflows/shared/squad-install-verifier.mjs \
8484

8585
# 7. Commit the generated files and open the bootstrap PR
8686
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
87+
node .github/workflows/shared/squad-install-verifier.mjs \
88+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
8789
git diff --cached --stat
8890
test -z "$(git diff --cached --diff-filter=D --name-only)"
8991
git commit -m "ci: add Squad agentic workflow"
@@ -364,6 +366,8 @@ done
364366
365367
```bash
366368
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
369+
node .github/workflows/shared/squad-install-verifier.mjs \
370+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
367371
git diff --cached --stat
368372
test -z "$(git diff --cached --diff-filter=D --name-only)"
369373
git commit -m "ci: add Squad agentic workflow"
@@ -381,6 +385,16 @@ state under `.github/aw/`, the installed skills, and `.gitattributes`. Review
381385
the complete generated diff in the bootstrap PR, address Copilot review
382386
feedback, and wait for required checks. Merge only after human approval.
383387
388+
Consumer ignore rules such as `packages/` can silently omit the required
389+
`.github/aw/packages/` ownership JSON from directory staging. The staged verifier
390+
force-adds only the exact native package ownership JSON when ignored and
391+
untracked, never unrelated ignored files. It checks every manifest-required
392+
source, lock, runtime, skill, manifest and ownership file in the Git index
393+
against the verified working-tree bytes. Missing metadata, failed staging,
394+
omitted required files or staged digest mismatches stop the install before
395+
commit/push. Never force-add a directory or glob; rerun the gate after edits or
396+
restaging, including package upgrades.
397+
384398
`gh aw add` may also create `.vscode/settings.json` to enable Copilot for
385399
Markdown workflow files. The command above intentionally leaves that optional
386400
editor setting untracked. Delete it if you do not want the local setting, or

‎packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ tools:
1111
when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR."
1212
- name: "gh aw"
1313
description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set."
14-
when: "Installing the immutable native Squad package and compiling its seven workflows into deterministic .lock.yml files."
14+
when: "Installing the immutable native Squad package and compiling its eight workflows into deterministic .lock.yml files."
1515
---
1616

1717
## Context
@@ -146,7 +146,7 @@ gh aw add "bradygaster/squad/workflows@${SQUAD_SHA}"
146146

147147
The nested `workflows/aw.yml` is the only supported distribution registration.
148148
It isolates package auto-discovery from unrelated repository skills and agents,
149-
and installs exactly seven workflows, fifteen runtime resources, and one
149+
and installs exactly eight workflows, seventeen runtime resources, and one
150150
`gh-aw-enlistment` skill at the same resolved revision:
151151

152152
- `squad.md` + `squad.lock.yml`
@@ -156,11 +156,12 @@ and installs exactly seven workflows, fifteen runtime resources, and one
156156
- `squad-retro.md` + `squad-retro.lock.yml`
157157
- `squad-improvement-worker.md` + `squad-improvement-worker.lock.yml`
158158
- `squad-bootstrap.md` + `squad-bootstrap.lock.yml`
159+
- `squad-command-router.md` + `squad-command-router.lock.yml`
159160

160161
`squad-improvement-worker` is part of the standard, coherent install above —
161162
not a separate opt-in add-on. It stays dormant until a maintainer approves a
162163
governance-scoped retrospective proposal (see the gh-aw guide's retrospective
163-
auto-implementation section); installing it alongside the other six keeps the
164+
auto-implementation section); installing it alongside the other seven keeps the
164165
full stack consistent and avoids a second bootstrap pass later.
165166

166167
Report/proposal-only is the default. Ordinary fixes require the explicit
@@ -220,7 +221,7 @@ node .github/workflows/shared/squad-install-verifier.mjs \
220221
This must run after any first-install approval and before committing. Success
221222
criteria:
222223

223-
- All seven workflows compile successfully.
224+
- All eight workflows compile successfully.
224225
- The **only** permitted warning is the known `squad.md` bot-trigger warning: it
225226
configures both slash-command and `github-actions[bot]` triggers, and the bot
226227
trigger is required for controlled worker-continuation dispatches.
@@ -230,7 +231,7 @@ criteria:
230231
### 6. Require the verifier to prove the complete consumer contract
231232

232233
- **STOP** if the verifier reports a missing source/lock pair, missing package
233-
ownership record, stale source/resource digest, incomplete seven-workflow
234+
ownership record, stale source/resource digest, incomplete eight-workflow
234235
registration, or mixed revision.
235236
- Use only the recovery commands printed by the verifier. They reinstall the
236237
complete package at one immutable revision; never repair one workflow or
@@ -258,6 +259,8 @@ Stage **only** the documented generated surfaces, then verify the staged set:
258259

259260
```bash
260261
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
262+
node .github/workflows/shared/squad-install-verifier.mjs \
263+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
261264
git diff --cached --stat
262265
# No deletions should be staged:
263266
test -z "$(git diff --cached --diff-filter=D --name-only)" || { echo "STOP: staged deletions"; exit 1; }
@@ -267,6 +270,15 @@ test -z "$(git diff --cached --diff-filter=D --name-only)" || { echo "STOP: stag
267270
edits to **unrelated files**, or committed **log/diagnostic output**. Re-scope with
268271
explicit `git add -- <path>` — never `git add .`, `git add -A`, or `git commit -a`.
269272

273+
Consumer rules such as `packages/` can silently ignore the required ownership
274+
JSON under `.github/aw/packages/`. The staged verifier force-adds only the exact
275+
native package ownership JSON when it is ignored and untracked. It then verifies
276+
every manifest-required source, lock, runtime, skill, manifest and ownership
277+
file against the validated working-tree bytes in a snapshot of the Git index.
278+
**STOP before commit/push** on missing metadata, a staging failure, an omitted
279+
required file or a staged digest mismatch. Never force-add a directory or glob.
280+
Rerun this gate after changing or restaging any installation file.
281+
270282
### 8. Commit, push, and open the bootstrap PR to the captured default branch
271283

272284
```bash
@@ -360,6 +372,8 @@ node .github/workflows/shared/squad-install-verifier.mjs \
360372
--verify-install --source-revision "${SQUAD_SHA}" --strict-compile
361373

362374
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
375+
node .github/workflows/shared/squad-install-verifier.mjs \
376+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
363377
git commit -m "ci: add Squad agentic workflow"
364378
git push -u origin HEAD
365379
gh pr create --base "${default_branch}" \

‎packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md‎

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ tools:
1111
when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR."
1212
- name: "gh aw"
1313
description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set."
14-
when: "Installing the immutable native Squad package and compiling its seven workflows into deterministic .lock.yml files."
14+
when: "Installing the immutable native Squad package and compiling its eight workflows into deterministic .lock.yml files."
1515
---
1616

1717
## Context
@@ -146,7 +146,7 @@ gh aw add "bradygaster/squad/workflows@${SQUAD_SHA}"
146146

147147
The nested `workflows/aw.yml` is the only supported distribution registration.
148148
It isolates package auto-discovery from unrelated repository skills and agents,
149-
and installs exactly seven workflows, fifteen runtime resources, and one
149+
and installs exactly eight workflows, seventeen runtime resources, and one
150150
`gh-aw-enlistment` skill at the same resolved revision:
151151

152152
- `squad.md` + `squad.lock.yml`
@@ -156,11 +156,12 @@ and installs exactly seven workflows, fifteen runtime resources, and one
156156
- `squad-retro.md` + `squad-retro.lock.yml`
157157
- `squad-improvement-worker.md` + `squad-improvement-worker.lock.yml`
158158
- `squad-bootstrap.md` + `squad-bootstrap.lock.yml`
159+
- `squad-command-router.md` + `squad-command-router.lock.yml`
159160

160161
`squad-improvement-worker` is part of the standard, coherent install above —
161162
not a separate opt-in add-on. It stays dormant until a maintainer approves a
162163
governance-scoped retrospective proposal (see the gh-aw guide's retrospective
163-
auto-implementation section); installing it alongside the other six keeps the
164+
auto-implementation section); installing it alongside the other seven keeps the
164165
full stack consistent and avoids a second bootstrap pass later.
165166

166167
Report/proposal-only is the default. Ordinary fixes require the explicit
@@ -220,7 +221,7 @@ node .github/workflows/shared/squad-install-verifier.mjs \
220221
This must run after any first-install approval and before committing. Success
221222
criteria:
222223

223-
- All seven workflows compile successfully.
224+
- All eight workflows compile successfully.
224225
- The **only** permitted warning is the known `squad.md` bot-trigger warning: it
225226
configures both slash-command and `github-actions[bot]` triggers, and the bot
226227
trigger is required for controlled worker-continuation dispatches.
@@ -230,7 +231,7 @@ criteria:
230231
### 6. Require the verifier to prove the complete consumer contract
231232

232233
- **STOP** if the verifier reports a missing source/lock pair, missing package
233-
ownership record, stale source/resource digest, incomplete seven-workflow
234+
ownership record, stale source/resource digest, incomplete eight-workflow
234235
registration, or mixed revision.
235236
- Use only the recovery commands printed by the verifier. They reinstall the
236237
complete package at one immutable revision; never repair one workflow or
@@ -258,6 +259,8 @@ Stage **only** the documented generated surfaces, then verify the staged set:
258259

259260
```bash
260261
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
262+
node .github/workflows/shared/squad-install-verifier.mjs \
263+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
261264
git diff --cached --stat
262265
# No deletions should be staged:
263266
test -z "$(git diff --cached --diff-filter=D --name-only)" || { echo "STOP: staged deletions"; exit 1; }
@@ -267,6 +270,15 @@ test -z "$(git diff --cached --diff-filter=D --name-only)" || { echo "STOP: stag
267270
edits to **unrelated files**, or committed **log/diagnostic output**. Re-scope with
268271
explicit `git add -- <path>` — never `git add .`, `git add -A`, or `git commit -a`.
269272

273+
Consumer rules such as `packages/` can silently ignore the required ownership
274+
JSON under `.github/aw/packages/`. The staged verifier force-adds only the exact
275+
native package ownership JSON when it is ignored and untracked. It then verifies
276+
every manifest-required source, lock, runtime, skill, manifest and ownership
277+
file against the validated working-tree bytes in a snapshot of the Git index.
278+
**STOP before commit/push** on missing metadata, a staging failure, an omitted
279+
required file or a staged digest mismatch. Never force-add a directory or glob.
280+
Rerun this gate after changing or restaging any installation file.
281+
270282
### 8. Commit, push, and open the bootstrap PR to the captured default branch
271283

272284
```bash
@@ -360,6 +372,8 @@ node .github/workflows/shared/squad-install-verifier.mjs \
360372
--verify-install --source-revision "${SQUAD_SHA}" --strict-compile
361373

362374
git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/
375+
node .github/workflows/shared/squad-install-verifier.mjs \
376+
--verify-staged-install --stage-ownership --source-revision "${SQUAD_SHA}" || exit 1
363377
git commit -m "ci: add Squad agentic workflow"
364378
git push -u origin HEAD
365379
gh pr create --base "${default_branch}" \

‎scripts/gh-aw-hosted-e2e.mjs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
TRIGGER_PROBE_DESTINATION,
2222
checkSource,
2323
verifyInstall,
24+
verifyStagedInstall,
2425
} from '../workflows/shared/squad-install-verifier.mjs';
2526

2627
const TRUSTED_SOURCE = Object.freeze({
@@ -802,6 +803,10 @@ function hosted(args, repositoryRoot) {
802803
const installPaths = ['.gitattributes', '.github/aw', '.github/workflows', '.github/skills', '.vscode']
803804
.filter((path) => existsSync(resolve(checkout, path)));
804805
runChild('git', ['add', '--', ...installPaths], { cwd: checkout });
806+
const staged = verifyStagedInstall(checkout, { expectedRevision: sourceSha, stageOwnership: true });
807+
if (staged.failures.length > 0) {
808+
throw new Error(`STOP: required installation files could not be staged and verified:\n${staged.failures.join('\n')}`);
809+
}
805810
runChild('git', ['commit', '-m', 'ci: install Squad agentic workflows'], { cwd: checkout });
806811
const installStartedAt = Date.now();
807812
const installation = createAndMergePr({

‎scripts/sync-templates.mjs‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,10 @@ for (const relFile of sourceFiles) {
117117
targets.push(join(AGENT_MD_TARGET, AGENT_MD_FILE));
118118
}
119119

120+
if (relFile === 'skills/gh-aw-enlistment/SKILL.md') {
121+
targets.push(join(ROOT, 'workflows', relFile));
122+
}
123+
120124
if (targets.length === 0) continue;
121125

122126
for (const dest of targets) {

0 commit comments

Comments
 (0)