From 29b64be3bc42970ce7764d768c611e6bcfe1c551 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 07:21:40 +0300 Subject: [PATCH 1/9] feat(workflows): add Squad implementation mode Closes #1681 - Add /squad implement dispatch for regular issues and ready epic tasks - Isolate repository edits in a private implementation worker workflow - Guard dependency handling, duplicate PR detection, concurrency, and PR file scope - Document installation, permissions, execution waves, and CI token behavior - gh aw compile squad-implement-worker --strict --approve - gh aw compile squad --strict --approve - npm run lint:docs - The new worker reuses SQUAD_GITHUB_APP_PRIVATE_KEY and SQUAD_GITHUB_TOKEN only through the existing shared Squad bootstrap - The main workflow remains read-only and dispatches a private worker through a bounded safe output - Worker changes are restricted by allowed source branches, allowed files, protected-file review, and one PR per run Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- README.md | 4 +- docs/src/content/docs/guide/gh-aw.md | 97 +++++++++++++++++++++--- workflows/squad-implement-worker.md | 106 +++++++++++++++++++++++++++ workflows/squad.md | 83 ++++++++++++++++++++- 4 files changed, 277 insertions(+), 13 deletions(-) create mode 100644 workflows/squad-implement-worker.md diff --git a/README.md b/README.md index 47a4ba3ce..c3029bb31 100644 --- a/README.md +++ b/README.md @@ -535,9 +535,10 @@ If you use [GitHub Agentic Workflows](https://github.blog/changelog/2025-05-19-g ### Install ```bash +gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev gh aw add bradygaster/squad/workflows/squad.md@dev gh aw compile -git add .github/workflows/ && git commit -m "Add Squad workflow" && git push +git add .github/workflows/ .gitattributes && git commit -m "Add Squad workflow" && git push ``` > `@dev` pulls the latest modes and fixes; switch to `@main` once gh-aw support is stable. @@ -552,6 +553,7 @@ git add .github/workflows/ && git commit -m "Add Squad workflow" && git push | `/squad cast-member ` | Add a team member | | `/squad retire ` | Remove a team member | | `/squad status` | Check current team | +| `/squad implement` | Implement an issue or dispatch ready tasks from an epic | ### Casting brief tip diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 02be692b7..ea6831c5b 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -26,14 +26,24 @@ gh api --method PUT repos/{owner}/{repo}/actions/permissions/workflow \ -f default_workflow_permissions=read \ -F can_approve_pull_request_reviews=true -# 3. Add the Squad workflow to your repo +# 3. Add the Squad workflows to your repo +gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev gh aw add bradygaster/squad/workflows/squad.md@dev -# 4. Compile the workflow to a lock file +# 4. Compile the workflows to lock files gh aw compile -# 5. Commit and push the changes -git add . +# 5. Commit and push the workflow sources and generated files +git add -- \ + .gitattributes \ + .github/aw/actions-lock.json \ + .github/workflows/squad.md \ + .github/workflows/squad.lock.yml \ + .github/workflows/squad-implement-worker.md \ + .github/workflows/squad-implement-worker.lock.yml \ + .github/workflows/shared/squad.md \ + .github/workflows/shared/planning-ontology.md \ + .github/workflows/shared/planning-policy.md git commit -m "ci: add Squad agentic workflow" git push @@ -79,12 +89,16 @@ a link for you to create the pull request manually. A manually created pull request is authored by your account, and GitHub does not allow authors to approve their own pull requests. -### Install the workflow +### Install the workflows ```bash +gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev gh aw add bradygaster/squad/workflows/squad.md@dev ``` +Install the private worker first so the main workflow can validate its +`dispatch-workflow` target during compilation. + :::note[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. ::: @@ -92,15 +106,15 @@ gh aw add bradygaster/squad/workflows/squad.md@dev This registers the Squad workflow in your repository's agentic workflow configuration. -### Compile to a lock file +### Compile to lock files ```bash gh aw compile ``` -Compiling resolves the workflow definition (including the shared bootstrap -component) into a deterministic `.github/workflows/squad.lock.yml` file. This -lock file is what GitHub Actions actually executes. +Compiling resolves both workflow definitions and their shared imports into +deterministic `.lock.yml` files. These lock files are what GitHub Actions +actually executes. ### Commit the workflow files @@ -109,8 +123,12 @@ git add -- \ .gitattributes \ .github/aw/actions-lock.json \ .github/workflows/squad.md \ + .github/workflows/squad.lock.yml \ + .github/workflows/squad-implement-worker.md \ + .github/workflows/squad-implement-worker.lock.yml \ .github/workflows/shared/squad.md \ - .github/workflows/squad.lock.yml + .github/workflows/shared/planning-ontology.md \ + .github/workflows/shared/planning-policy.md git commit -m "ci: add Squad agentic workflow" git push ``` @@ -200,6 +218,7 @@ PR review comment. | `/squad plan activate` | Create GitHub issues from an accepted plan | | `/squad plan activate phase {N}` | Create GitHub issues for only Phase N of the accepted plan | | `/squad plan revise ` | Revise the current plan based on your feedback | +| `/squad implement` | Implement an issue, or start the next ready wave of an epic | ### Where you can use slash commands @@ -604,6 +623,60 @@ next — no need to memorize the command sequence. --- +## Implementing issues + +After `/squad plan activate` creates the implementation backlog, run: + +``` +/squad implement +``` + +### Regular issues + +On a regular issue, Squad: + +1. Dispatches an isolated implementation worker +2. Checks that every issue listed in `Depends on:` is closed +3. Routes the work using the issue's `squad:{member}` label +4. Implements and validates the acceptance criteria +5. Opens a focused pull request that closes the issue + +The main Squad workflow retains its narrow cast and planning permissions. Only +the private implementation worker can edit repository files, and it delivers +changes through gh-aw's guarded `create-pull-request` safe output. + +### Epics + +On an epic, Squad finds its open child issues through native sub-issue +relationships and `Parent: #N` metadata. It then: + +1. Excludes tasks with open dependencies +2. Excludes tasks that already have an implementation pull request +3. Dispatches up to three ready tasks to isolated implementation workers +4. Comments with the dispatched, blocked, existing, and deferred tasks + +Each worker creates its own branch and pull request. After those pull requests +are merged, run `/squad implement` on the epic again to start the next +dependency wave. Automatic continuation after merge is not currently enabled. + +:::note[Repository setting] +Pull-request delivery requires **Settings → Actions → General → Workflow +permissions → Allow GitHub Actions to create and approve pull requests**. +::: + +:::note[Pull request CI] +Pull requests created with the default `GITHUB_TOKEN` do not trigger other +workflow runs. Set `GH_AW_CI_TRIGGER_TOKEN` to a suitable fine-grained PAT if +implementation pull requests must start repository CI automatically. +::: + +:::note[Manual runs] +From **Actions → Squad → Run workflow**, enter `implement` as the command and +provide the target issue number. +::: + +--- + ## Connect vs. Adopt Squad supports two ways to bring in a team from another repository. @@ -761,6 +834,7 @@ are used. State does not persist across runs. To update your compiled workflow after pulling upstream changes: ```bash +gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev gh aw add bradygaster/squad/workflows/squad.md@dev ``` @@ -785,6 +859,8 @@ gh aw compile | 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 accept creates fewer issues than expected | `create-issue` safe-output has a max of 30 | Split into multiple plan/accept cycles for very large decompositions | +| `/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 | --- @@ -792,4 +868,5 @@ gh aw compile - [Squad README](https://github.com/bradygaster/squad#readme) — project overview and local CLI usage - [Workflow definition](https://github.com/bradygaster/squad/blob/dev/workflows/squad.md) — full slash command specification +- [Implementation worker](https://github.com/bradygaster/squad/blob/dev/workflows/squad-implement-worker.md) — isolated issue implementation workflow - [Bootstrap component](https://github.com/bradygaster/squad/blob/dev/workflows/shared/squad.md) — activation and artifact lifecycle diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md new file mode 100644 index 000000000..5317fdf11 --- /dev/null +++ b/workflows/squad-implement-worker.md @@ -0,0 +1,106 @@ +--- +name: Squad Implement Worker +run-name: "Squad implement #${{ github.event.inputs.issue_number }}" +description: Implement one Squad issue and open a pull request +private: true +on: + workflow_dispatch: + inputs: + issue_number: + description: Issue number to implement + required: true + type: string +permissions: + contents: read + copilot-requests: write + issues: read + pull-requests: read +concurrency: + group: "squad-implement-${{ github.event.inputs.issue_number }}" + cancel-in-progress: false +network: + allowed: + - defaults +imports: + - shared/squad.md +tools: + edit: + bash: true + github: + mode: gh-proxy + toolsets: [default] +safe-outputs: + create-pull-request: + title-prefix: "[squad] " + labels: [squad] + max: 1 + allowed-base-branches: + - "squad/*" + allowed-branches: + - "squad/implement-*" + allowed-files: + - "*" + - "app/**" + - "bin/**" + - "cmd/**" + - "config/**" + - "docs/**" + - "examples/**" + - "internal/**" + - "lib/**" + - "packages/**" + - "public/**" + - "samples/**" + - "scripts/**" + - "src/**" + - "test/**" + - "tests/**" + - "tools/**" + protected-files: request_review + max-patch-files: 500 + expires: 14d + add-comment: + max: 3 + target: "*" +--- + +# Squad Implementation Worker + +Implement issue `${{ github.event.inputs.issue_number }}` in the current +repository and open a focused pull request. + +## Gather Context + +1. Read the issue title, body, labels, state, and relevant comments. +2. Stop with a comment if the issue is closed. +3. Parse its `Depends on:` line. Check every referenced issue and stop with a + blocker comment if any dependency remains open. +4. Check for an existing open pull request whose branch starts with + `squad/implement-${{ github.event.inputs.issue_number }}-` or whose body + closes this issue. If one exists, comment with its URL and stop. +5. Read `.squad/team.md` and `.squad/routing.md`. Route work to the member named + by the `squad:{member}` label, or let the Lead choose specialists. + +## Implement + +1. Inspect the repository and implement the smallest complete change satisfying + every acceptance criterion. +2. Use the routed Squad specialists for design, implementation, tests, and + review. Keep delegation bounded to this issue. +3. Do not change `.github/workflows/`, `.github/agents/`, `.github/aw/`, or + `.squad/`. +4. Run the smallest existing build, test, and lint commands covering the change. +5. Review the final diff against the issue acceptance criteria. + +## Open Pull Request + +Use the `create-pull-request` safe-output: + +- Branch: `squad/implement-${{ github.event.inputs.issue_number }}-{short-slug}` +- Title: `Implement #${{ github.event.inputs.issue_number }}: {issue-title}` +- Body: summarize implementation and validation, including + `Closes #${{ github.event.inputs.issue_number }}`. +- Files: include only files required for this issue. + +If the repository already satisfies the issue, comment with evidence and do not +create an empty pull request. diff --git a/workflows/squad.md b/workflows/squad.md index 36860d66f..1005a17d3 100644 --- a/workflows/squad.md +++ b/workflows/squad.md @@ -17,6 +17,10 @@ on: description: 'Squad command (e.g., cast, connect org/repo, adopt org/repo, status)' required: false default: 'cast' + issue_number: + description: 'Issue number to implement when run manually' + required: false + type: string permissions: contents: read copilot-requests: write @@ -53,6 +57,10 @@ safe-outputs: max: 75 add-comment: max: 20 + target: "*" + dispatch-workflow: + workflows: [squad-implement-worker] + max: 3 --- ## Comment Search Rules (all modes) @@ -67,7 +75,19 @@ safe-outputs: Read slash command from: `github.event.comment.body` (issue/PR comment), `github.event.issue.body` (issue body), or `github.event.inputs.command` (workflow_dispatch, default: `cast`). -The activation job ran `squad init --preset default` producing generic `.squad/` scaffolding. Cast mode REPLACES this. This workflow never creates/modifies `.github/workflows/`. +- **Issue body:** `github.event.issue.body` — the full issue description +- **Issue comment:** `github.event.comment.body` — the full comment text +- **PR review comment:** `github.event.comment.body` — the full comment text +- **Workflow dispatch:** `github.event.inputs.command` — manual input (default: `cast`) +- **Manual issue target:** `github.event.inputs.issue_number` — issue number for + `/squad implement` runs started from the Actions tab + +The activation job already ran `squad init --preset default`, which produced a +generic 5-agent team (lead, reviewer, devrel, security, docs) in `.squad/`. Cast +mode REPLACES this scaffolding with a team tailored to the repository. + +This workflow does not create or modify files under `.github/workflows/`. +Repository owners must configure Copilot setup steps separately when needed. ## Modes @@ -95,6 +115,7 @@ The activation job ran `squad init --preset default` producing generic `.squad/` | `/squad plan accept implementation phase {N}` | Plan Accept Implementation | | `/squad plan activate` | Plan Activate | | `/squad plan activate phase {N}` | Plan Activate | +| `/squad implement` | Implement | | `/squad` (no args) | Cast | ## Parse Command @@ -104,7 +125,7 @@ The activation job ran `squad init --preset default` producing generic `.squad/` 3. Match **longest-prefix-first**: - `plan accept implementation` (3), `plan accept scope` (3), `plan program revise` (3) - `plan implementation` (2), `plan program` (2), `plan activate` (2), `plan validate` (2), `plan accept` (2), `plan revise` (2), `triage revise` (2) - - `cast-member` (1), `plan` (1), `cast`, `connect`, `adopt`, `retire`, `status`, `research`, `triage` + - `cast-member` (1), `plan` (1), `cast`, `connect`, `adopt`, `retire`, `status`, `research`, `triage`, `implement` 4. Default to `cast` if empty. 5. **Phase selector:** If remaining args contain `phase {N}`, extract N. @@ -285,6 +306,64 @@ Read-only team composition report. --- +#### Implement Mode + +Implement mode dispatches an isolated implementation worker for a regular issue. +When invoked on an epic, it dispatches workers for up to three currently +unblocked children. + +**Acknowledge:** Post `🤖 Squad is preparing implementation…` using the +`add-comment` safe-output. + +##### Step 1: Validate and Gather Context + +1. Resolve the target issue number from `github.event.inputs.issue_number` for a + workflow dispatch, otherwise from the triggering issue. If invoked from a + pull request review comment, explain that `/squad implement` must be run from + the target issue. +2. Read the target issue title, body, labels, state, and relevant comments. +3. Find open child issues using native GitHub sub-issue relationships. Also + include open issues whose body contains a + `Parent: #{target-issue-number}` line for compatibility with older plans. +4. If child issues exist, treat the target as an epic and follow the Epic + Dispatch procedure below. Do not implement the epic body directly. +5. If no child issues exist, use the `dispatch-workflow` safe-output to dispatch + `squad-implement-worker` with `issue_number` set to the target issue number. +6. Post a comment linking the dispatched worker run. The worker performs + dependency, duplicate pull request, routing, implementation, and validation + checks. + +##### Epic Dispatch + +For each open child issue: + +1. Parse its `Depends on:` line and check the state of every referenced issue. +2. Exclude children with any open dependency. +3. Exclude children that already have an open pull request whose branch starts + with `squad/implement-{child-number}-` or whose body closes that child. +4. Sort ready children by issue number and select at most three. + +For each selected child, use the `dispatch-workflow` safe-output: + +```json +{ + "type": "dispatch_workflow", + "workflow_name": "squad-implement-worker", + "inputs": { + "issue_number": "{child-issue-number}" + } +} +``` + +Post a comment on the epic listing the dispatched children, blocked children, +children with existing implementation pull requests, and any ready children +deferred by the concurrency limit. If no child is ready, post the blocker +summary and do not dispatch a workflow. Run `/squad implement` on the epic again +after the current implementation pull requests are merged to start the next +dependency wave. + +--- + #### Research Mode Deep analysis → structured findings comment. Read-only + comment. Works on open/closed issues. From f107fc1a13adee27cbc8c488dc6ebc2d38c494e3 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 07:26:29 +0300 Subject: [PATCH 2/9] fix(docs): avoid unsafe git add pattern Closes #1681 ## Summary - Split the README staging example into an explicit path-scoped command - Avoid the repository security scanner's unsafe git add pattern ## Test Plan - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index c3029bb31..1455cfe17 100644 --- a/README.md +++ b/README.md @@ -538,7 +538,11 @@ If you use [GitHub Agentic Workflows](https://github.blog/changelog/2025-05-19-g gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev gh aw add bradygaster/squad/workflows/squad.md@dev gh aw compile -git add .github/workflows/ .gitattributes && git commit -m "Add Squad workflow" && git push +git add -- \ + .github/workflows/ \ + .gitattributes +git commit -m "Add Squad workflow" +git push ``` > `@dev` pulls the latest modes and fixes; switch to `@main` once gh-aw support is stable. From bb47cddf4fce07beac5233605eadba11e529527a Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 11:11:14 +0300 Subject: [PATCH 3/9] fix(workflows): scope one-command installer package Part of #1681 - Move the gh-aw package manifest under workflows/ - Install only the Squad dispatcher, worker, and shared dependencies - Avoid importing unrelated repository agents and skills - npx vitest run test/gh-aw-implement-workflow.test.ts - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- README.md | 3 +- docs/src/content/docs/guide/gh-aw.md | 13 +++---- test/gh-aw-implement-workflow.test.ts | 50 +++++++++++++++++++++++++++ workflows/README.md | 8 +++++ workflows/aw.yml | 7 ++++ 5 files changed, 71 insertions(+), 10 deletions(-) create mode 100644 test/gh-aw-implement-workflow.test.ts create mode 100644 workflows/README.md create mode 100644 workflows/aw.yml diff --git a/README.md b/README.md index 1455cfe17..fbf013ba4 100644 --- a/README.md +++ b/README.md @@ -535,8 +535,7 @@ If you use [GitHub Agentic Workflows](https://github.blog/changelog/2025-05-19-g ### Install ```bash -gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev -gh aw add bradygaster/squad/workflows/squad.md@dev +gh aw add bradygaster/squad/workflows@dev gh aw compile git add -- \ .github/workflows/ \ diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index ea6831c5b..6692149fe 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -27,8 +27,7 @@ gh api --method PUT repos/{owner}/{repo}/actions/permissions/workflow \ -F can_approve_pull_request_reviews=true # 3. Add the Squad workflows to your repo -gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev -gh aw add bradygaster/squad/workflows/squad.md@dev +gh aw add bradygaster/squad/workflows@dev # 4. Compile the workflows to lock files gh aw compile @@ -92,12 +91,11 @@ approve their own pull requests. ### Install the workflows ```bash -gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev -gh aw add bradygaster/squad/workflows/squad.md@dev +gh aw add bradygaster/squad/workflows@dev ``` -Install the private worker first so the main workflow can validate its -`dispatch-workflow` target during compilation. +The package manifest installs the private worker first so the main workflow can +validate its `dispatch-workflow` target during compilation. :::note[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. @@ -834,8 +832,7 @@ are used. State does not persist across runs. To update your compiled workflow after pulling upstream changes: ```bash -gh aw add bradygaster/squad/workflows/squad-implement-worker.md@dev -gh aw add bradygaster/squad/workflows/squad.md@dev +gh aw add bradygaster/squad/workflows@dev ``` This re-compiles the workflow from source. If you have local customizations in your compiled `.github/workflows/squad-*.lock.yml`, they will be overwritten — keep customizations in the source `.md` files instead. diff --git a/test/gh-aw-implement-workflow.test.ts b/test/gh-aw-implement-workflow.test.ts new file mode 100644 index 000000000..a620ec026 --- /dev/null +++ b/test/gh-aw-implement-workflow.test.ts @@ -0,0 +1,50 @@ +import { describe, expect, it } from 'vitest'; +import { readFileSync } from 'node:fs'; +import { dirname, resolve } from 'node:path'; +import { fileURLToPath } from 'node:url'; + +const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..'); + +function read(relativePath: string): string { + return readFileSync(resolve(ROOT, relativePath), 'utf-8'); +} + +describe('gh-aw implement workflows', () => { + const dispatcher = read('workflows/squad.md'); + const worker = read('workflows/squad-implement-worker.md'); + const guide = read('docs/src/content/docs/guide/gh-aw.md'); + const manifest = read('workflows/aw.yml'); + + it('keeps repository editing isolated to the dispatch-only worker', () => { + expect(dispatcher).not.toMatch(/^tools:\r?\n\s+edit:/m); + expect(worker).toContain('private: false'); + expect(worker).not.toContain('slash_command:'); + expect(worker).toMatch(/^tools:\r?\n\s+edit:/m); + expect(worker).toContain('protected-files: request_review'); + }); + + it('bounds dispatch and serializes workers for the same issue', () => { + expect(dispatcher).toContain('workflows: [squad-implement-worker]'); + expect(dispatcher).toMatch(/dispatch-workflow:\r?\n\s+workflows: \[squad-implement-worker\]\r?\n\s+max: 3/); + expect(worker).toContain('group: "squad-implement-${{ github.event.inputs.issue_number }}"'); + expect(worker).toContain('cancel-in-progress: false'); + }); + + it('guards implementation branches, files, dependencies, and duplicate PRs', () => { + expect(worker).toContain('- "squad/implement-*"'); + expect(worker).not.toMatch(/allowed-files:\r?\n\s+- "\*"/); + expect(worker).toContain('Do not change `.github/workflows/`, `.github/agents/`, `.github/aw/`, or'); + expect(worker).toContain('blocker comment if any dependency remains open'); + expect(worker).toContain('Check for an existing open pull request'); + }); + + it('documents one-command installation in dependency order', () => { + const workerIndex = manifest.indexOf('squad-implement-worker.md'); + const dispatcherIndex = manifest.indexOf('squad.md'); + + expect(workerIndex).toBeGreaterThan(-1); + expect(dispatcherIndex).toBeGreaterThan(workerIndex); + expect(guide).toContain('gh aw add bradygaster/squad/workflows@dev'); + expect(guide).toContain('The package manifest installs the dedicated worker first'); + }); +}); diff --git a/workflows/README.md b/workflows/README.md new file mode 100644 index 000000000..4297d946d --- /dev/null +++ b/workflows/README.md @@ -0,0 +1,8 @@ +# Squad Agentic Workflows + +Install the Squad dispatcher, implementation worker, and shared workflow +components with: + +```bash +gh aw add bradygaster/squad/workflows@dev +``` diff --git a/workflows/aw.yml b/workflows/aw.yml new file mode 100644 index 000000000..32a7ad9bf --- /dev/null +++ b/workflows/aw.yml @@ -0,0 +1,7 @@ +manifest-version: "1" +name: Squad Agentic Workflows +emoji: "🤖" +description: Cast, plan, and implement work with a Squad AI team +includes: + - squad-implement-worker.md + - squad.md From 5224e17160c509981f5956cd5c9ccef74b9511db Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 11:13:48 +0300 Subject: [PATCH 4/9] fix(docs): use explicit one-command workflow install Part of #1681 - Install both workflow sources in one gh aw add invocation - Preserve dependency order without importing unrelated package artifacts - Remove the overly broad repository package manifest - Remote gh aw add with both workflow references - npx vitest run test/gh-aw-implement-workflow.test.ts - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- README.md | 4 +++- docs/src/content/docs/guide/gh-aw.md | 16 +++++++++++----- test/gh-aw-implement-workflow.test.ts | 8 +++----- workflows/README.md | 8 -------- workflows/aw.yml | 7 ------- 5 files changed, 17 insertions(+), 26 deletions(-) delete mode 100644 workflows/README.md delete mode 100644 workflows/aw.yml diff --git a/README.md b/README.md index fbf013ba4..8f63d99b4 100644 --- a/README.md +++ b/README.md @@ -535,7 +535,9 @@ If you use [GitHub Agentic Workflows](https://github.blog/changelog/2025-05-19-g ### Install ```bash -gh aw add bradygaster/squad/workflows@dev +gh aw add \ + bradygaster/squad/workflows/squad-implement-worker.md@dev \ + bradygaster/squad/workflows/squad.md@dev gh aw compile git add -- \ .github/workflows/ \ diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 6692149fe..32e13b2e1 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -27,7 +27,9 @@ gh api --method PUT repos/{owner}/{repo}/actions/permissions/workflow \ -F can_approve_pull_request_reviews=true # 3. Add the Squad workflows to your repo -gh aw add bradygaster/squad/workflows@dev +gh aw add \ + bradygaster/squad/workflows/squad-implement-worker.md@dev \ + bradygaster/squad/workflows/squad.md@dev # 4. Compile the workflows to lock files gh aw compile @@ -91,11 +93,13 @@ approve their own pull requests. ### Install the workflows ```bash -gh aw add bradygaster/squad/workflows@dev +gh aw add \ + bradygaster/squad/workflows/squad-implement-worker.md@dev \ + bradygaster/squad/workflows/squad.md@dev ``` -The package manifest installs the private worker first so the main workflow can -validate its `dispatch-workflow` target during compilation. +The single command installs the dedicated worker first, then the main workflow +that dispatches it. :::note[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. @@ -832,7 +836,9 @@ are used. State does not persist across runs. To update your compiled workflow after pulling upstream changes: ```bash -gh aw add bradygaster/squad/workflows@dev +gh aw add \ + bradygaster/squad/workflows/squad-implement-worker.md@dev \ + bradygaster/squad/workflows/squad.md@dev ``` This re-compiles the workflow from source. If you have local customizations in your compiled `.github/workflows/squad-*.lock.yml`, they will be overwritten — keep customizations in the source `.md` files instead. diff --git a/test/gh-aw-implement-workflow.test.ts b/test/gh-aw-implement-workflow.test.ts index a620ec026..80497f3c8 100644 --- a/test/gh-aw-implement-workflow.test.ts +++ b/test/gh-aw-implement-workflow.test.ts @@ -13,7 +13,6 @@ describe('gh-aw implement workflows', () => { const dispatcher = read('workflows/squad.md'); const worker = read('workflows/squad-implement-worker.md'); const guide = read('docs/src/content/docs/guide/gh-aw.md'); - const manifest = read('workflows/aw.yml'); it('keeps repository editing isolated to the dispatch-only worker', () => { expect(dispatcher).not.toMatch(/^tools:\r?\n\s+edit:/m); @@ -39,12 +38,11 @@ describe('gh-aw implement workflows', () => { }); it('documents one-command installation in dependency order', () => { - const workerIndex = manifest.indexOf('squad-implement-worker.md'); - const dispatcherIndex = manifest.indexOf('squad.md'); + const workerIndex = guide.indexOf('bradygaster/squad/workflows/squad-implement-worker.md@dev'); + const dispatcherIndex = guide.indexOf('bradygaster/squad/workflows/squad.md@dev'); expect(workerIndex).toBeGreaterThan(-1); expect(dispatcherIndex).toBeGreaterThan(workerIndex); - expect(guide).toContain('gh aw add bradygaster/squad/workflows@dev'); - expect(guide).toContain('The package manifest installs the dedicated worker first'); + expect(guide).toContain('The single command installs the dedicated worker first'); }); }); diff --git a/workflows/README.md b/workflows/README.md deleted file mode 100644 index 4297d946d..000000000 --- a/workflows/README.md +++ /dev/null @@ -1,8 +0,0 @@ -# Squad Agentic Workflows - -Install the Squad dispatcher, implementation worker, and shared workflow -components with: - -```bash -gh aw add bradygaster/squad/workflows@dev -``` diff --git a/workflows/aw.yml b/workflows/aw.yml deleted file mode 100644 index 32a7ad9bf..000000000 --- a/workflows/aw.yml +++ /dev/null @@ -1,7 +0,0 @@ -manifest-version: "1" -name: Squad Agentic Workflows -emoji: "🤖" -description: Cast, plan, and implement work with a Squad AI team -includes: - - squad-implement-worker.md - - squad.md From fc0050cc97fda69ddd0b6a1ee247c3235ffe7264 Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 11:31:02 +0300 Subject: [PATCH 5/9] fix(workflows): require typed worker dispatch Part of #1681 ## Summary - Use the workflow-specific worker dispatch tool instead of the generic safe output - Require a numeric issue input for every selected child - Prevent malformed placeholder dispatches from failing the safe-output job ## Test Plan - gh aw compile squad --strict --approve - npx vitest run test/gh-aw-implement-workflow.test.ts - Two worker runs completed successfully in tamirdresher/my-new-cli-mock Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- test/gh-aw-implement-workflow.test.ts | 2 ++ workflows/squad.md | 19 +++++++++++-------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/test/gh-aw-implement-workflow.test.ts b/test/gh-aw-implement-workflow.test.ts index 80497f3c8..e74826c40 100644 --- a/test/gh-aw-implement-workflow.test.ts +++ b/test/gh-aw-implement-workflow.test.ts @@ -25,6 +25,8 @@ describe('gh-aw implement workflows', () => { it('bounds dispatch and serializes workers for the same issue', () => { expect(dispatcher).toContain('workflows: [squad-implement-worker]'); expect(dispatcher).toMatch(/dispatch-workflow:\r?\n\s+workflows: \[squad-implement-worker\]\r?\n\s+max: 3/); + expect(dispatcher).toContain('Never call the generic `dispatch_workflow` tool'); + expect(dispatcher).toContain('Never emit a dispatch without a'); expect(worker).toContain('group: "squad-implement-${{ github.event.inputs.issue_number }}"'); expect(worker).toContain('cancel-in-progress: false'); }); diff --git a/workflows/squad.md b/workflows/squad.md index 1005a17d3..737e88db8 100644 --- a/workflows/squad.md +++ b/workflows/squad.md @@ -327,8 +327,9 @@ unblocked children. `Parent: #{target-issue-number}` line for compatibility with older plans. 4. If child issues exist, treat the target as an epic and follow the Epic Dispatch procedure below. Do not implement the epic body directly. -5. If no child issues exist, use the `dispatch-workflow` safe-output to dispatch - `squad-implement-worker` with `issue_number` set to the target issue number. +5. If no child issues exist, call the workflow-specific + `squad_implement_worker` safe-output tool with `issue_number` set to the + target issue number. 6. Post a comment linking the dispatched worker run. The worker performs dependency, duplicate pull request, routing, implementation, and validation checks. @@ -343,18 +344,20 @@ For each open child issue: with `squad/implement-{child-number}-` or whose body closes that child. 4. Sort ready children by issue number and select at most three. -For each selected child, use the `dispatch-workflow` safe-output: +For each selected child, call the workflow-specific `squad_implement_worker` +safe-output tool with this input: ```json { - "type": "dispatch_workflow", - "workflow_name": "squad-implement-worker", - "inputs": { - "issue_number": "{child-issue-number}" - } + "issue_number": "{child-issue-number}" } ``` +Never call the generic `dispatch_workflow` tool. Never emit a dispatch without a +non-empty numeric `issue_number`. Emit exactly one workflow-specific dispatch +per selected child, and only report a child as dispatched after the tool returns +success. + Post a comment on the epic listing the dispatched children, blocked children, children with existing implementation pull requests, and any ready children deferred by the concurrency limit. If no child is ready, post the blocker From d7e7ef0d2137184cfe7f9e235c49097a6e5d0b5d Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 16:14:38 +0300 Subject: [PATCH 6/9] feat(workflows): continue epic implementation after merge - Relay merged implementation PRs through the existing worker to the Squad dispatcher - Refill a maximum of three active epic implementation slots automatically - Document rolling continuation and add structural regression coverage - gh aw compile squad and squad-implement-worker --strict --approve --no-emit - npx vitest run test/gh-aw-implement-workflow.test.ts - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- docs/src/content/docs/guide/gh-aw.md | 18 +++++++--- test/gh-aw-implement-workflow.test.ts | 15 ++++++++- workflows/squad-implement-worker.md | 47 +++++++++++++++++++++++---- workflows/squad.md | 20 ++++++++---- 4 files changed, 82 insertions(+), 18 deletions(-) diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 32e13b2e1..dac6ed728 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -654,12 +654,22 @@ relationships and `Parent: #N` metadata. It then: 1. Excludes tasks with open dependencies 2. Excludes tasks that already have an implementation pull request -3. Dispatches up to three ready tasks to isolated implementation workers +3. Keeps up to three implementation pull requests active 4. Comments with the dispatched, blocked, existing, and deferred tasks -Each worker creates its own branch and pull request. After those pull requests -are merged, run `/squad implement` on the epic again to start the next -dependency wave. Automatic continuation after merge is not currently enabled. +Each worker creates its own branch and pull request. When one of those pull +requests merges, the existing worker resolves the parent epic and dispatches +the main Squad workflow in implement mode. Squad then dispatches enough ready +children to refill the three active slots. This continues until no open +children remain, without installing a third workflow. + +For example, an epic with ten independent tasks starts three workers. Each merge +automatically starts one replacement, keeping three implementation pull requests +active until the final task is dispatched. Dependencies may temporarily reduce +the active count when no additional child is ready. + +`/squad implement` remains available as a manual recovery command if a run is +cancelled or an external change requires the epic to be reevaluated. :::note[Repository setting] Pull-request delivery requires **Settings → Actions → General → Workflow diff --git a/test/gh-aw-implement-workflow.test.ts b/test/gh-aw-implement-workflow.test.ts index e74826c40..c4ba1d959 100644 --- a/test/gh-aw-implement-workflow.test.ts +++ b/test/gh-aw-implement-workflow.test.ts @@ -27,10 +27,23 @@ describe('gh-aw implement workflows', () => { expect(dispatcher).toMatch(/dispatch-workflow:\r?\n\s+workflows: \[squad-implement-worker\]\r?\n\s+max: 3/); expect(dispatcher).toContain('Never call the generic `dispatch_workflow` tool'); expect(dispatcher).toContain('Never emit a dispatch without a'); - expect(worker).toContain('group: "squad-implement-${{ github.event.inputs.issue_number }}"'); + expect(worker).toContain( + 'group: "squad-implement-${{ github.event.inputs.issue_number || github.event.pull_request.number }}"', + ); expect(worker).toContain('cancel-in-progress: false'); }); + it('continues epic execution after implementation PRs merge', () => { + expect(dispatcher).not.toMatch(/pull_request:\r?\n\s+types: \[closed\]/); + expect(worker).toMatch(/pull_request:\r?\n\s+types: \[closed\]/); + expect(worker).toContain("startsWith(github.event.pull_request.head.ref, 'squad/implement-')"); + expect(worker).toContain('workflows: [squad]'); + expect(worker).toContain('"command": "implement"'); + expect(worker).toContain('Never call the generic `dispatch_workflow` tool'); + expect(dispatcher).toContain('available-slots = max(0, 3 - active-implementation-count)'); + expect(dispatcher).toContain('fills newly available slots'); + }); + it('guards implementation branches, files, dependencies, and duplicate PRs', () => { expect(worker).toContain('- "squad/implement-*"'); expect(worker).not.toMatch(/allowed-files:\r?\n\s+- "\*"/); diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md index 5317fdf11..b5a30d47e 100644 --- a/workflows/squad-implement-worker.md +++ b/workflows/squad-implement-worker.md @@ -1,8 +1,8 @@ --- name: Squad Implement Worker -run-name: "Squad implement #${{ github.event.inputs.issue_number }}" -description: Implement one Squad issue and open a pull request -private: true +run-name: "Squad implement — ${{ github.event.inputs.issue_number || github.event.pull_request.head.ref }}" +description: Implement one Squad issue or continue its parent epic after merge +private: false on: workflow_dispatch: inputs: @@ -10,13 +10,19 @@ on: description: Issue number to implement required: true type: string + pull_request: + types: [closed] +if: >- + github.event_name != 'pull_request' || + (github.event.pull_request.merged == true && + startsWith(github.event.pull_request.head.ref, 'squad/implement-')) permissions: contents: read copilot-requests: write issues: read pull-requests: read concurrency: - group: "squad-implement-${{ github.event.inputs.issue_number }}" + group: "squad-implement-${{ github.event.inputs.issue_number || github.event.pull_request.number }}" cancel-in-progress: false network: allowed: @@ -62,12 +68,41 @@ safe-outputs: add-comment: max: 3 target: "*" + dispatch-workflow: + workflows: [squad] + max: 1 --- # Squad Implementation Worker -Implement issue `${{ github.event.inputs.issue_number }}` in the current -repository and open a focused pull request. +This workflow has two modes: + +1. A `workflow_dispatch` implements issue + `${{ github.event.inputs.issue_number }}` and opens a focused pull request. +2. A merged `pull_request` continues the parent epic. + +## Continue Parent Epic After Merge + +For a merged pull request: + +1. Extract the child issue number from the + `squad/implement-{issue-number}-` head branch. +2. Read the child issue and resolve its parent epic using the native parent + relationship, falling back to its `Parent: #N` body line. +3. If no parent epic exists, emit `noop` and stop. +4. Call the workflow-specific `squad` safe-output tool exactly once: + +```json +{ + "command": "implement", + "issue_number": "{parent-epic-number}" +} +``` + +Never call the generic `dispatch_workflow` tool. Never edit files or create a +pull request in this mode. Stop after the `squad` workflow is dispatched. + +The remaining instructions apply only to `workflow_dispatch`. ## Gather Context diff --git a/workflows/squad.md b/workflows/squad.md index 737e88db8..470884b54 100644 --- a/workflows/squad.md +++ b/workflows/squad.md @@ -310,7 +310,8 @@ Read-only team composition report. Implement mode dispatches an isolated implementation worker for a regular issue. When invoked on an epic, it dispatches workers for up to three currently -unblocked children. +unblocked children. The worker relays merged implementation pull requests back +to this mode so it can automatically refill the parent epic's available slots. **Acknowledge:** Post `🤖 Squad is preparing implementation…` using the `add-comment` safe-output. @@ -340,9 +341,12 @@ For each open child issue: 1. Parse its `Depends on:` line and check the state of every referenced issue. 2. Exclude children with any open dependency. -3. Exclude children that already have an open pull request whose branch starts +3. Find children that already have an open pull request whose branch starts with `squad/implement-{child-number}-` or whose body closes that child. -4. Sort ready children by issue number and select at most three. + These are active implementation children. +4. Calculate `available-slots = max(0, 3 - active-implementation-count)`. +5. Exclude active implementation children from the ready set. +6. Sort ready children by issue number and select at most `available-slots`. For each selected child, call the workflow-specific `squad_implement_worker` safe-output tool with this input: @@ -360,10 +364,12 @@ success. Post a comment on the epic listing the dispatched children, blocked children, children with existing implementation pull requests, and any ready children -deferred by the concurrency limit. If no child is ready, post the blocker -summary and do not dispatch a workflow. Run `/squad implement` on the epic again -after the current implementation pull requests are merged to start the next -dependency wave. +deferred because all three slots are occupied. If no child is ready or no slot +is available, post the status summary and do not dispatch a workflow. + +After each implementation pull request merges, this workflow runs again and +fills newly available slots. Continue until the epic has no open children. +`/squad implement` remains available as a manual recovery command. --- From 570ea57d0b5900b263765f054c7f0bac0b4b3a7d Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 16:33:54 +0300 Subject: [PATCH 7/9] fix(workflows): authorize trusted workflow dispatches ## Summary - Allow github-actions bot activation for the two-workflow implementation chain - Propagate gh-aw context into both workflow dispatch targets - Document and test workflow-to-workflow activation ## Test Plan - gh aw compile squad and squad-implement-worker --strict --approve --no-emit - npx vitest run test/gh-aw-implement-workflow.test.ts - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- docs/src/content/docs/guide/gh-aw.md | 4 ++++ test/gh-aw-implement-workflow.test.ts | 4 ++++ workflows/squad-implement-worker.md | 5 +++++ workflows/squad.md | 5 +++++ 4 files changed, 18 insertions(+) diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index dac6ed728..583509237 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -663,6 +663,10 @@ the main Squad workflow in implement mode. Squad then dispatches enough ready children to refill the three active slots. This continues until no open children remain, without installing a third workflow. +Both workflows accept gh-aw's propagated `aw_context` and allow the repository's +`github-actions[bot]` to pass the workflow-dispatch activation gate. Human +slash commands retain the normal repository-role checks. + For example, an epic with ten independent tasks starts three workers. Each merge automatically starts one replacement, keeping three implementation pull requests active until the final task is dispatched. Dependencies may temporarily reduce diff --git a/test/gh-aw-implement-workflow.test.ts b/test/gh-aw-implement-workflow.test.ts index c4ba1d959..9ac7cd3f2 100644 --- a/test/gh-aw-implement-workflow.test.ts +++ b/test/gh-aw-implement-workflow.test.ts @@ -23,6 +23,10 @@ describe('gh-aw implement workflows', () => { }); it('bounds dispatch and serializes workers for the same issue', () => { + expect(dispatcher).toContain('bots: ["github-actions[bot]"]'); + expect(worker).toContain('bots: ["github-actions[bot]"]'); + expect(dispatcher).toContain('aw_context:'); + expect(worker).toContain('aw_context:'); expect(dispatcher).toContain('workflows: [squad-implement-worker]'); expect(dispatcher).toMatch(/dispatch-workflow:\r?\n\s+workflows: \[squad-implement-worker\]\r?\n\s+max: 3/); expect(dispatcher).toContain('Never call the generic `dispatch_workflow` tool'); diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md index b5a30d47e..7e0eace15 100644 --- a/workflows/squad-implement-worker.md +++ b/workflows/squad-implement-worker.md @@ -4,12 +4,17 @@ run-name: "Squad implement — ${{ github.event.inputs.issue_number || github.ev description: Implement one Squad issue or continue its parent epic after merge private: false on: + bots: ["github-actions[bot]"] workflow_dispatch: inputs: issue_number: description: Issue number to implement required: true type: string + aw_context: + description: Originating agentic workflow context + required: false + type: string pull_request: types: [closed] if: >- diff --git a/workflows/squad.md b/workflows/squad.md index 470884b54..7fe5e73b9 100644 --- a/workflows/squad.md +++ b/workflows/squad.md @@ -5,6 +5,7 @@ description: Cast, connect, or adopt a Squad AI team for your repository emoji: "🤖" private: false on: + bots: ["github-actions[bot]"] slash_command: name: squad events: @@ -21,6 +22,10 @@ on: description: 'Issue number to implement when run manually' required: false type: string + aw_context: + description: 'Originating agentic workflow context' + required: false + type: string permissions: contents: read copilot-requests: write From 3dd243914394910cd2fb37ec9e0e655ba39623ab Mon Sep 17 00:00:00 2001 From: Copilot Date: Tue, 11 Aug 2026 17:08:43 +0300 Subject: [PATCH 8/9] fix(workflows): dispatch continuation on default branch ## Summary - Pin the merge-triggered Squad relay to the repository default branch - Avoid dispatch failures after merged implementation branches are deleted - Cover and document the ref selection ## Test Plan - gh aw compile squad and squad-implement-worker --strict --approve --no-emit - npx vitest run test/gh-aw-implement-workflow.test.ts - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- docs/src/content/docs/guide/gh-aw.md | 4 +++- test/gh-aw-implement-workflow.test.ts | 1 + workflows/squad-implement-worker.md | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 583509237..d29b641b7 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -665,7 +665,9 @@ children remain, without installing a third workflow. Both workflows accept gh-aw's propagated `aw_context` and allow the repository's `github-actions[bot]` to pass the workflow-dispatch activation gate. Human -slash commands retain the normal repository-role checks. +slash commands retain the normal repository-role checks. The merge relay +targets the repository's default branch so deleting a merged implementation +branch cannot prevent the continuation dispatch. For example, an epic with ten independent tasks starts three workers. Each merge automatically starts one replacement, keeping three implementation pull requests diff --git a/test/gh-aw-implement-workflow.test.ts b/test/gh-aw-implement-workflow.test.ts index 9ac7cd3f2..fae6839c2 100644 --- a/test/gh-aw-implement-workflow.test.ts +++ b/test/gh-aw-implement-workflow.test.ts @@ -42,6 +42,7 @@ describe('gh-aw implement workflows', () => { expect(worker).toMatch(/pull_request:\r?\n\s+types: \[closed\]/); expect(worker).toContain("startsWith(github.event.pull_request.head.ref, 'squad/implement-')"); expect(worker).toContain('workflows: [squad]'); + expect(worker).toContain('target-ref: ${{ github.event.repository.default_branch }}'); expect(worker).toContain('"command": "implement"'); expect(worker).toContain('Never call the generic `dispatch_workflow` tool'); expect(dispatcher).toContain('available-slots = max(0, 3 - active-implementation-count)'); diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md index 7e0eace15..bc522e0de 100644 --- a/workflows/squad-implement-worker.md +++ b/workflows/squad-implement-worker.md @@ -76,6 +76,7 @@ safe-outputs: dispatch-workflow: workflows: [squad] max: 1 + target-ref: ${{ github.event.repository.default_branch }} --- # Squad Implementation Worker From 2432600db3c7ca6764b90fe820c9f80a1024af26 Mon Sep 17 00:00:00 2001 From: Copilot Date: Wed, 12 Aug 2026 07:29:20 +0300 Subject: [PATCH 9/9] fix(workflows): preserve implementation file guardrails ## Summary - Restore the restricted implementation worker allowlist after rebasing - Keep root-level source files supported without permitting arbitrary files ## Test Plan - npx vitest run test/gh-aw-implement-workflow.test.ts - npm run lint:docs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 2587b35f-a675-4bf1-a761-265efc31cc23 --- workflows/squad-implement-worker.md | 32 ++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/workflows/squad-implement-worker.md b/workflows/squad-implement-worker.md index bc522e0de..0111a06e2 100644 --- a/workflows/squad-implement-worker.md +++ b/workflows/squad-implement-worker.md @@ -50,9 +50,36 @@ safe-outputs: allowed-branches: - "squad/implement-*" allowed-files: - - "*" + - "*.c" + - "*.cc" + - "*.cpp" + - "*.cs" + - "*.css" + - "*.fs" + - "*.go" + - "*.html" + - "*.java" + - "*.js" + - "*.jsx" + - "*.json" + - "*.md" + - "*.mjs" + - "*.py" + - "*.rb" + - "*.rs" + - "*.sh" + - "*.toml" + - "*.ts" + - "*.tsx" + - "*.yaml" + - "*.yml" + - "Dockerfile*" + - "LICENSE*" + - "Makefile" + - "api/**" - "app/**" - "bin/**" + - "client/**" - "cmd/**" - "config/**" - "docs/**" @@ -63,10 +90,13 @@ safe-outputs: - "public/**" - "samples/**" - "scripts/**" + - "server/**" + - "services/**" - "src/**" - "test/**" - "tests/**" - "tools/**" + - "web/**" protected-files: request_review max-patch-files: 500 expires: 14d