From ad8eb281e07b338d7d1263cbfbf07f9efe3d652c Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Thu, 24 Sep 2026 11:40:27 -0700 Subject: [PATCH 1/4] docs: require Issues before gh-aw install Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .github/agents.md | 13 +++-- .../skills/gh-aw-enlistment/SKILL.md | 52 ++++++++++++++++-- README.md | 7 +++ docs/src/content/docs/guide/gh-aw.md | 53 ++++++++++++++++++- .../skills/gh-aw-enlistment/SKILL.md | 52 ++++++++++++++++-- .../skills/gh-aw-enlistment/SKILL.md | 52 ++++++++++++++++-- templates/skills/gh-aw-enlistment/SKILL.md | 52 ++++++++++++++++-- test/gh-aw-enlistment-skill.test.ts | 26 +++++++++ 8 files changed, 282 insertions(+), 25 deletions(-) diff --git a/.github/agents.md b/.github/agents.md index 07f51a55e..10f824ca4 100644 --- a/.github/agents.md +++ b/.github/agents.md @@ -23,10 +23,15 @@ GitHub Agentic Workflows (`gh-aw`) are composable AI workflows triggered by slas > Agentic Workflows, execute the complete > [seven-step quick start](../docs/src/content/docs/guide/gh-aw.md#quick-start) > in their repository. Do not only quote or run the `gh aw add` command below. -> The supported path configures workflow-created pull requests, installs and -> validates the complete generated artifact set, commits it on an isolated -> branch, and opens a human-reviewed bootstrap PR. Stop at that PR; the human -> merges it. `/squad` slash commands become active only after that merge reaches +> The supported path verifies that GitHub Issues are enabled (and enables them +> when the authenticated user has repository administration permission), +> configures workflow-created pull requests, installs and validates the complete +> generated artifact set, commits it on an isolated branch, and opens a +> human-reviewed bootstrap PR. If disabled Issues cannot be enabled, stop before +> installation and ask a repository administrator to enable them. `/squad` +> commands use issue comments, and bootstrap creates a research/proposals issue. +> Stop at the bootstrap PR; the human merges it. +> `/squad` slash commands become active only after that merge reaches > the repository's default branch. The quick start installs this workflow set: diff --git a/.squad-templates/skills/gh-aw-enlistment/SKILL.md b/.squad-templates/skills/gh-aw-enlistment/SKILL.md index cb713dd6f..2355bbab9 100644 --- a/.squad-templates/skills/gh-aw-enlistment/SKILL.md +++ b/.squad-templates/skills/gh-aw-enlistment/SKILL.md @@ -7,8 +7,8 @@ source: "Operationalized from the authoritative Squad gh-aw guide (docs/src/cont triggers: [set up Squad agentic workflows, enlist this repo in Squad, enlist my repository in Squad, install Squad gh-aw workflows, install Squad agentic workflows, add Squad gh aw workflows, bootstrap Squad in this repo, onboard this repo to Squad, set up /squad slash commands, gh aw add squad] tools: - name: "gh" - description: "GitHub CLI — repo identity, Actions permissions, PR creation, review request, and check watching." - when: "Every step: preflight identity/auth, enabling Actions-created PRs, opening and watching the bootstrap PR." + description: "GitHub CLI — repo identity, Issues and Actions settings, PR creation, review request, and check watching." + when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR." - name: "gh aw" description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set." when: "Installing the seven @dev workflows and compiling them into deterministic .lock.yml files." @@ -28,6 +28,12 @@ The authoritative source is `docs/src/content/docs/guide/gh-aw.md` (mirrored at `https://bradygaster.github.io/squad/docs/guide/gh-aw/`). If that guide and this skill ever disagree, the guide wins — re-read it before proceeding. +GitHub Issues are a hard prerequisite: `/squad` commands arrive as issue +comments, and the merged bootstrap creates a research/proposals issue. Detect +and enable Issues before creating the bootstrap branch or installing workflows, +so the install cannot produce a PR whose post-merge bootstrap is unable to +complete. + **Portability contract:** resolve every repository identifier (owner, repo, default branch) **at runtime**. Never hardcode a placeholder like `{owner}/{repo}`. The only fixed identifier is the Squad source itself — `bradygaster/squad/workflows/...@dev` — @@ -73,10 +79,37 @@ git status --short - Confirm Copilot is enabled for the repository where checkable; the activation run and the requested `@copilot` review both depend on it. -### 1. Allow Actions-created PRs while keeping the default token read-only +### 1. Require GitHub Issues, then allow Actions-created PRs with a read-only token + +Check the REST API's `has_issues` field first. If Issues are disabled, enable +them before touching the install: + +```bash +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + echo "GitHub Issues are disabled; enabling them before workflow installation." + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi +fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} +``` + +Reading `.has_issues` is non-mutating. Updating it through +`PATCH /repos/{owner}/{repo}` requires repository administration permission. +If the PATCH fails, **STOP before branch creation or `gh aw add`** and ask an +administrator to enable **Settings → General → Features → Issues**. Do not +continue with a bootstrap PR that cannot complete after merge. -Squad opens PRs through GitHub Actions. Enable that **without** widening the -default workflow token: +Squad also opens PRs through GitHub Actions. Enable that **without** widening +the default workflow token: ```bash gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ @@ -295,6 +328,12 @@ gh pr checks --watch owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')" +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent +fi +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true @@ -353,6 +392,9 @@ gh pr merge --squash # auto-merge before human review. NEVER. - ❌ **Hardcoding repository identifiers.** Always resolve `owner/repo` and the default branch at runtime with `gh repo view`. +- ❌ **Installing while GitHub Issues are disabled.** `/squad` commands and the + bootstrap research/proposals issue require Issues. Enable them first, or stop + before installation if repository administration permission is unavailable. - ❌ **Blanket staging** (`git add .` / `-A` / `git commit -a`). Stage only `.gitattributes`, `.github/aw/`, `.github/workflows/`, `.github/skills/`, by path. - ❌ **Approving unknown safe updates.** Approve ONLY `SQUAD_GITHUB_APP_PRIVATE_KEY`, diff --git a/README.md b/README.md index c4ba74d47..54b964ec1 100644 --- a/README.md +++ b/README.md @@ -561,6 +561,13 @@ If you use [GitHub Agentic Workflows](https://github.blog/changelog/2025-05-19-g +Squad requires GitHub Issues: slash commands are issue comments, and the merged +bootstrap creates a research/proposals issue. Follow the +[supported seven-step quick start](docs/src/content/docs/guide/gh-aw.md#quick-start), +which checks and enables Issues before installation when the authenticated user +has repository administration permission, and stops before creating a bootstrap +PR when an administrator must enable them. + ```bash gh aw add \ bradygaster/squad/workflows/squad.md@dev \ diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 62e56f614..3a09667ac 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -33,7 +33,23 @@ owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')" gh extension list | grep -q 'github/gh-aw' || gh extension install github/gh-aw -# 2. Allow GitHub Actions to create pull requests +# 2. Require GitHub Issues, then allow GitHub Actions to create pull requests +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + echo "GitHub Issues are disabled; enabling them before workflow installation." + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun this quick start." >&2 + exit 1 + fi +fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} + gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read \ -F can_approve_pull_request_reviews=true @@ -104,6 +120,15 @@ contains the complete seven-workflow set. For a repeatable upgrade, pin all seven entries to one reviewed commit as described in [Upgrading the workflows](#upgrading-the-workflows). +Step 2 deliberately checks Issues before creating the bootstrap branch or +installing any workflow. Squad commands are issue comments, and the merged +bootstrap creates a research/proposals issue; without Issues, the installation +PR could merge but the bootstrap journey could not complete. Reading +`.has_issues` is safe for normal repository access. Enabling it through +`PATCH /repos/{owner}/{repo}` requires repository administration permission. If +that update fails, stop before installation and ask an administrator to enable +**Settings → General → Features → Issues**, then rerun the quick start. + > 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 @@ -136,6 +161,7 @@ issues exist. | Requirement | Details | |-------------|---------| | GitHub repo with Copilot | Copilot must be enabled for the repository | +| GitHub Issues | Required for `/squad` issue comments and the bootstrap research/proposals issue; a repository administrator must be available to enable Issues if they are disabled | | `gh` CLI | [Install the GitHub CLI](https://cli.github.com/) and authenticate with `gh auth login` | | `gh aw` extension | `gh extension install github/gh-aw` | @@ -143,6 +169,30 @@ issues exist. ## Setup +### Enable GitHub Issues + +Squad receives commands through issue comments, and `squad-bootstrap` creates a +research/proposals issue after the workflow-installation PR merges. Check the +repository setting and enable it before installing any workflows: + +```bash +owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" + +if [ "${issues_enabled}" != "true" ]; then + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: A repository administrator must enable Settings > General > Features > Issues." >&2 + exit 1 + fi +fi +``` + +The GET is non-mutating, and the conditional PATCH makes this safe to rerun. +Changing `has_issues` requires repository administration permission. If the +PATCH fails, do not continue to `gh aw add`: have an administrator enable Issues +in repository settings, then rerun the supported quick start. + ### Allow workflow-created pull requests Squad opens pull requests through GitHub Actions. Enable this repository setting @@ -384,6 +434,7 @@ Use this checklist for the initial bootstrap and after any workflow update: | Stage | Action | Expected evidence | |-------|--------|-------------------| +| Repository readiness | Confirm `.has_issues` is `true`; if it is `false`, enable it before installing workflows | GitHub Issues are available for `/squad` comments and the bootstrap research/proposals issue; insufficient administration permission stops the install before a bootstrap PR is created | | Install | Run the seven-workflow `gh aw add` command on a bootstrap branch | All seven `.md`/`.lock.yml` pairs exist, with shared imports, `.github/aw/`, installed skills, and `.gitattributes` included in the diff | | Compile | Review any first-install safe-update report, approve only the documented entries, then run `gh aw compile --strict` without approval | All seven workflows succeed, only documented warnings remain, and all fourteen source/lock files exist | | Bootstrap review | Open the PR, request `@copilot`, wait for checks, and merge only after human approval | The default branch receives the complete generated install as one human-reviewable change | 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 cb713dd6f..2355bbab9 100644 --- a/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md +++ b/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md @@ -7,8 +7,8 @@ source: "Operationalized from the authoritative Squad gh-aw guide (docs/src/cont triggers: [set up Squad agentic workflows, enlist this repo in Squad, enlist my repository in Squad, install Squad gh-aw workflows, install Squad agentic workflows, add Squad gh aw workflows, bootstrap Squad in this repo, onboard this repo to Squad, set up /squad slash commands, gh aw add squad] tools: - name: "gh" - description: "GitHub CLI — repo identity, Actions permissions, PR creation, review request, and check watching." - when: "Every step: preflight identity/auth, enabling Actions-created PRs, opening and watching the bootstrap PR." + description: "GitHub CLI — repo identity, Issues and Actions settings, PR creation, review request, and check watching." + when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR." - name: "gh aw" description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set." when: "Installing the seven @dev workflows and compiling them into deterministic .lock.yml files." @@ -28,6 +28,12 @@ The authoritative source is `docs/src/content/docs/guide/gh-aw.md` (mirrored at `https://bradygaster.github.io/squad/docs/guide/gh-aw/`). If that guide and this skill ever disagree, the guide wins — re-read it before proceeding. +GitHub Issues are a hard prerequisite: `/squad` commands arrive as issue +comments, and the merged bootstrap creates a research/proposals issue. Detect +and enable Issues before creating the bootstrap branch or installing workflows, +so the install cannot produce a PR whose post-merge bootstrap is unable to +complete. + **Portability contract:** resolve every repository identifier (owner, repo, default branch) **at runtime**. Never hardcode a placeholder like `{owner}/{repo}`. The only fixed identifier is the Squad source itself — `bradygaster/squad/workflows/...@dev` — @@ -73,10 +79,37 @@ git status --short - Confirm Copilot is enabled for the repository where checkable; the activation run and the requested `@copilot` review both depend on it. -### 1. Allow Actions-created PRs while keeping the default token read-only +### 1. Require GitHub Issues, then allow Actions-created PRs with a read-only token + +Check the REST API's `has_issues` field first. If Issues are disabled, enable +them before touching the install: + +```bash +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + echo "GitHub Issues are disabled; enabling them before workflow installation." + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi +fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} +``` + +Reading `.has_issues` is non-mutating. Updating it through +`PATCH /repos/{owner}/{repo}` requires repository administration permission. +If the PATCH fails, **STOP before branch creation or `gh aw add`** and ask an +administrator to enable **Settings → General → Features → Issues**. Do not +continue with a bootstrap PR that cannot complete after merge. -Squad opens PRs through GitHub Actions. Enable that **without** widening the -default workflow token: +Squad also opens PRs through GitHub Actions. Enable that **without** widening +the default workflow token: ```bash gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ @@ -295,6 +328,12 @@ gh pr checks --watch owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')" +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent +fi +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true @@ -353,6 +392,9 @@ gh pr merge --squash # auto-merge before human review. NEVER. - ❌ **Hardcoding repository identifiers.** Always resolve `owner/repo` and the default branch at runtime with `gh repo view`. +- ❌ **Installing while GitHub Issues are disabled.** `/squad` commands and the + bootstrap research/proposals issue require Issues. Enable them first, or stop + before installation if repository administration permission is unavailable. - ❌ **Blanket staging** (`git add .` / `-A` / `git commit -a`). Stage only `.gitattributes`, `.github/aw/`, `.github/workflows/`, `.github/skills/`, by path. - ❌ **Approving unknown safe updates.** Approve ONLY `SQUAD_GITHUB_APP_PRIVATE_KEY`, 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 cb713dd6f..2355bbab9 100644 --- a/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md +++ b/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md @@ -7,8 +7,8 @@ source: "Operationalized from the authoritative Squad gh-aw guide (docs/src/cont triggers: [set up Squad agentic workflows, enlist this repo in Squad, enlist my repository in Squad, install Squad gh-aw workflows, install Squad agentic workflows, add Squad gh aw workflows, bootstrap Squad in this repo, onboard this repo to Squad, set up /squad slash commands, gh aw add squad] tools: - name: "gh" - description: "GitHub CLI — repo identity, Actions permissions, PR creation, review request, and check watching." - when: "Every step: preflight identity/auth, enabling Actions-created PRs, opening and watching the bootstrap PR." + description: "GitHub CLI — repo identity, Issues and Actions settings, PR creation, review request, and check watching." + when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR." - name: "gh aw" description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set." when: "Installing the seven @dev workflows and compiling them into deterministic .lock.yml files." @@ -28,6 +28,12 @@ The authoritative source is `docs/src/content/docs/guide/gh-aw.md` (mirrored at `https://bradygaster.github.io/squad/docs/guide/gh-aw/`). If that guide and this skill ever disagree, the guide wins — re-read it before proceeding. +GitHub Issues are a hard prerequisite: `/squad` commands arrive as issue +comments, and the merged bootstrap creates a research/proposals issue. Detect +and enable Issues before creating the bootstrap branch or installing workflows, +so the install cannot produce a PR whose post-merge bootstrap is unable to +complete. + **Portability contract:** resolve every repository identifier (owner, repo, default branch) **at runtime**. Never hardcode a placeholder like `{owner}/{repo}`. The only fixed identifier is the Squad source itself — `bradygaster/squad/workflows/...@dev` — @@ -73,10 +79,37 @@ git status --short - Confirm Copilot is enabled for the repository where checkable; the activation run and the requested `@copilot` review both depend on it. -### 1. Allow Actions-created PRs while keeping the default token read-only +### 1. Require GitHub Issues, then allow Actions-created PRs with a read-only token + +Check the REST API's `has_issues` field first. If Issues are disabled, enable +them before touching the install: + +```bash +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + echo "GitHub Issues are disabled; enabling them before workflow installation." + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi +fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} +``` + +Reading `.has_issues` is non-mutating. Updating it through +`PATCH /repos/{owner}/{repo}` requires repository administration permission. +If the PATCH fails, **STOP before branch creation or `gh aw add`** and ask an +administrator to enable **Settings → General → Features → Issues**. Do not +continue with a bootstrap PR that cannot complete after merge. -Squad opens PRs through GitHub Actions. Enable that **without** widening the -default workflow token: +Squad also opens PRs through GitHub Actions. Enable that **without** widening +the default workflow token: ```bash gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ @@ -295,6 +328,12 @@ gh pr checks --watch owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')" +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent +fi +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true @@ -353,6 +392,9 @@ gh pr merge --squash # auto-merge before human review. NEVER. - ❌ **Hardcoding repository identifiers.** Always resolve `owner/repo` and the default branch at runtime with `gh repo view`. +- ❌ **Installing while GitHub Issues are disabled.** `/squad` commands and the + bootstrap research/proposals issue require Issues. Enable them first, or stop + before installation if repository administration permission is unavailable. - ❌ **Blanket staging** (`git add .` / `-A` / `git commit -a`). Stage only `.gitattributes`, `.github/aw/`, `.github/workflows/`, `.github/skills/`, by path. - ❌ **Approving unknown safe updates.** Approve ONLY `SQUAD_GITHUB_APP_PRIVATE_KEY`, diff --git a/templates/skills/gh-aw-enlistment/SKILL.md b/templates/skills/gh-aw-enlistment/SKILL.md index cb713dd6f..2355bbab9 100644 --- a/templates/skills/gh-aw-enlistment/SKILL.md +++ b/templates/skills/gh-aw-enlistment/SKILL.md @@ -7,8 +7,8 @@ source: "Operationalized from the authoritative Squad gh-aw guide (docs/src/cont triggers: [set up Squad agentic workflows, enlist this repo in Squad, enlist my repository in Squad, install Squad gh-aw workflows, install Squad agentic workflows, add Squad gh aw workflows, bootstrap Squad in this repo, onboard this repo to Squad, set up /squad slash commands, gh aw add squad] tools: - name: "gh" - description: "GitHub CLI — repo identity, Actions permissions, PR creation, review request, and check watching." - when: "Every step: preflight identity/auth, enabling Actions-created PRs, opening and watching the bootstrap PR." + description: "GitHub CLI — repo identity, Issues and Actions settings, PR creation, review request, and check watching." + when: "Every step: preflight identity/auth, requiring Issues, enabling Actions-created PRs, opening and watching the bootstrap PR." - name: "gh aw" description: "GitHub Agentic Workflows extension (github/gh-aw) — installs and strictly compiles the Squad workflow set." when: "Installing the seven @dev workflows and compiling them into deterministic .lock.yml files." @@ -28,6 +28,12 @@ The authoritative source is `docs/src/content/docs/guide/gh-aw.md` (mirrored at `https://bradygaster.github.io/squad/docs/guide/gh-aw/`). If that guide and this skill ever disagree, the guide wins — re-read it before proceeding. +GitHub Issues are a hard prerequisite: `/squad` commands arrive as issue +comments, and the merged bootstrap creates a research/proposals issue. Detect +and enable Issues before creating the bootstrap branch or installing workflows, +so the install cannot produce a PR whose post-merge bootstrap is unable to +complete. + **Portability contract:** resolve every repository identifier (owner, repo, default branch) **at runtime**. Never hardcode a placeholder like `{owner}/{repo}`. The only fixed identifier is the Squad source itself — `bradygaster/squad/workflows/...@dev` — @@ -73,10 +79,37 @@ git status --short - Confirm Copilot is enabled for the repository where checkable; the activation run and the requested `@copilot` review both depend on it. -### 1. Allow Actions-created PRs while keeping the default token read-only +### 1. Require GitHub Issues, then allow Actions-created PRs with a read-only token + +Check the REST API's `has_issues` field first. If Issues are disabled, enable +them before touching the install: + +```bash +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + echo "GitHub Issues are disabled; enabling them before workflow installation." + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi +fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} +``` + +Reading `.has_issues` is non-mutating. Updating it through +`PATCH /repos/{owner}/{repo}` requires repository administration permission. +If the PATCH fails, **STOP before branch creation or `gh aw add`** and ask an +administrator to enable **Settings → General → Features → Issues**. Do not +continue with a bootstrap PR that cannot complete after merge. -Squad opens PRs through GitHub Actions. Enable that **without** widening the -default workflow token: +Squad also opens PRs through GitHub Actions. Enable that **without** widening +the default workflow token: ```bash gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ @@ -295,6 +328,12 @@ gh pr checks --watch owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.name')" +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent +fi +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true @@ -353,6 +392,9 @@ gh pr merge --squash # auto-merge before human review. NEVER. - ❌ **Hardcoding repository identifiers.** Always resolve `owner/repo` and the default branch at runtime with `gh repo view`. +- ❌ **Installing while GitHub Issues are disabled.** `/squad` commands and the + bootstrap research/proposals issue require Issues. Enable them first, or stop + before installation if repository administration permission is unavailable. - ❌ **Blanket staging** (`git add .` / `-A` / `git commit -a`). Stage only `.gitattributes`, `.github/aw/`, `.github/workflows/`, `.github/skills/`, by path. - ❌ **Approving unknown safe updates.** Approve ONLY `SQUAD_GITHUB_APP_PRIVATE_KEY`, diff --git a/test/gh-aw-enlistment-skill.test.ts b/test/gh-aw-enlistment-skill.test.ts index f2858a66f..696212750 100644 --- a/test/gh-aw-enlistment-skill.test.ts +++ b/test/gh-aw-enlistment-skill.test.ts @@ -190,6 +190,18 @@ describe('gh-aw-enlistment skill', () => { expect(content).toContain('default_workflow_permissions=read'); }); + it('requires GitHub Issues before installation and stops when they cannot be enabled', () => { + expect(content).toContain('gh api "repos/${owner_repo}" --jq \'.has_issues\''); + expect(content).toContain( + 'gh api --method PATCH "repos/${owner_repo}"', + ); + expect(content).toContain('-F has_issues=true --silent'); + expect(content).toContain('requires repository administration permission'); + expect(content).toContain('STOP before branch creation or `gh aw add`'); + expect(content.indexOf("issues_enabled=")).toBeLessThan(content.indexOf('git switch -c')); + expect(content.indexOf("issues_enabled=")).toBeLessThan(content.indexOf('gh aw add \\')); + }); + it('forbids blanket staging and mandates explicit paths', () => { expect(content).toMatch(/git add \.|git add -A|git commit -a/); // referenced as an anti-pattern expect(content).toContain('git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/'); @@ -243,6 +255,20 @@ describe('gh-aw-enlistment skill', () => { expect(guide).not.toContain('repos/{owner}/{repo}/actions/permissions/workflow'); }); + it('requires Issues before installation and documents the admin-permission stop', () => { + const issuesCheck = guide.indexOf( + 'issues_enabled="$(gh api "repos/${owner_repo}" --jq \'.has_issues\')"', + ); + expect(issuesCheck).toBeGreaterThan(-1); + expect(guide).toContain('-F has_issues=true --silent'); + expect(guide).toContain('requires repository administration permission'); + expect(guide).toContain('do not continue to `gh aw add`'); + expect(issuesCheck).toBeLessThan(guide.indexOf('git switch -c chore/squad-gh-aw-bootstrap')); + expect(issuesCheck).toBeLessThan(guide.indexOf('gh aw add \\')); + expect(agentGuide).toContain('verifies that GitHub Issues are enabled'); + expect(agentGuide).toContain('bootstrap creates a research/proposals issue'); + }); + it('activates slash commands only after the bootstrap PR reaches the default branch', () => { expect(guide).toContain( 'Once the bootstrap PR is merged into the default branch, the `/squad` slash', From ad6af270c2856ce7e219bcc475eb3bc07464d11c Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Thu, 24 Sep 2026 14:12:22 -0700 Subject: [PATCH 2/4] docs: add gh-aw enlistment changeset Add patch release metadata for the CLI and SDK templates changed by PR #2072. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .changeset/require-issues-for-gh-aw.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 .changeset/require-issues-for-gh-aw.md diff --git a/.changeset/require-issues-for-gh-aw.md b/.changeset/require-issues-for-gh-aw.md new file mode 100644 index 000000000..4a150dd7d --- /dev/null +++ b/.changeset/require-issues-for-gh-aw.md @@ -0,0 +1,6 @@ +--- +"@bradygaster/squad-cli": patch +"@bradygaster/squad-sdk": patch +--- + +Require GitHub Issues to be enabled before installing Squad Agentic Workflows, and guide authorized administrators through enabling and verifying the repository setting before bootstrap. From 244d770847026066216ed5a094ac9286ee314abd Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Thu, 24 Sep 2026 14:10:07 -0700 Subject: [PATCH 3/4] docs: fail closed when enabling Issues Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .changeset/gh-aw-issues-prerequisite.md | 6 ++++ .../skills/gh-aw-enlistment/SKILL.md | 13 +++++++-- README.md | 17 +++++++++++ docs/src/content/docs/guide/gh-aw.md | 5 ++++ .../skills/gh-aw-enlistment/SKILL.md | 13 +++++++-- .../skills/gh-aw-enlistment/SKILL.md | 13 +++++++-- templates/skills/gh-aw-enlistment/SKILL.md | 13 +++++++-- test/gh-aw-enlistment-skill.test.ts | 29 +++++++++++++++++++ 8 files changed, 101 insertions(+), 8 deletions(-) create mode 100644 .changeset/gh-aw-issues-prerequisite.md diff --git a/.changeset/gh-aw-issues-prerequisite.md b/.changeset/gh-aw-issues-prerequisite.md new file mode 100644 index 000000000..eb855047a --- /dev/null +++ b/.changeset/gh-aw-issues-prerequisite.md @@ -0,0 +1,6 @@ +--- +"@bradygaster/squad-cli": patch +"@bradygaster/squad-sdk": patch +--- + +Require GitHub Issues to be enabled before installing Squad Agentic Workflows, and fail closed when the authenticated user cannot update the repository setting. diff --git a/.squad-templates/skills/gh-aw-enlistment/SKILL.md b/.squad-templates/skills/gh-aw-enlistment/SKILL.md index 2355bbab9..3cdacd84d 100644 --- a/.squad-templates/skills/gh-aw-enlistment/SKILL.md +++ b/.squad-templates/skills/gh-aw-enlistment/SKILL.md @@ -330,9 +330,18 @@ default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.n issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" if [ "${issues_enabled}" != "true" ]; then - gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi fi -test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true diff --git a/README.md b/README.md index 54b964ec1..8340764fe 100644 --- a/README.md +++ b/README.md @@ -569,6 +569,23 @@ has repository administration permission, and stops before creating a bootstrap PR when an administrator must enable them. ```bash +set -euo pipefail + +owner_repo="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')" +issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" +if [ "${issues_enabled}" != "true" ]; then + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: A repository administrator must enable Settings > General > Features > Issues." >&2 + exit 1 + fi +fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} + gh aw add \ bradygaster/squad/workflows/squad.md@dev \ bradygaster/squad/workflows/squad-implement-worker.md@dev \ diff --git a/docs/src/content/docs/guide/gh-aw.md b/docs/src/content/docs/guide/gh-aw.md index 3a09667ac..4e715ebf6 100644 --- a/docs/src/content/docs/guide/gh-aw.md +++ b/docs/src/content/docs/guide/gh-aw.md @@ -186,6 +186,11 @@ if [ "${issues_enabled}" != "true" ]; then exit 1 fi fi + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} ``` The GET is non-mutating, and the conditional PATCH makes this safe to rerun. 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 2355bbab9..3cdacd84d 100644 --- a/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md +++ b/packages/squad-cli/templates/skills/gh-aw-enlistment/SKILL.md @@ -330,9 +330,18 @@ default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.n issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" if [ "${issues_enabled}" != "true" ]; then - gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi fi -test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true 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 2355bbab9..3cdacd84d 100644 --- a/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md +++ b/packages/squad-sdk/templates/skills/gh-aw-enlistment/SKILL.md @@ -330,9 +330,18 @@ default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.n issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" if [ "${issues_enabled}" != "true" ]; then - gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi fi -test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true diff --git a/templates/skills/gh-aw-enlistment/SKILL.md b/templates/skills/gh-aw-enlistment/SKILL.md index 2355bbab9..3cdacd84d 100644 --- a/templates/skills/gh-aw-enlistment/SKILL.md +++ b/templates/skills/gh-aw-enlistment/SKILL.md @@ -330,9 +330,18 @@ default_branch="$(gh repo view --json defaultBranchRef --jq '.defaultBranchRef.n issues_enabled="$(gh api "repos/${owner_repo}" --jq '.has_issues')" if [ "${issues_enabled}" != "true" ]; then - gh api --method PATCH "repos/${owner_repo}" -F has_issues=true --silent + if ! gh api --method PATCH "repos/${owner_repo}" \ + -F has_issues=true --silent; then + echo "STOP: GitHub Issues are disabled and could not be enabled." >&2 + echo "A repository administrator must enable Settings > General > Features > Issues, then rerun enlistment." >&2 + exit 1 + fi fi -test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" + +test "$(gh api "repos/${owner_repo}" --jq '.has_issues')" = "true" || { + echo "STOP: GitHub Issues must be enabled before installing Squad workflows." >&2 + exit 1 +} gh api --method PUT "repos/${owner_repo}/actions/permissions/workflow" \ -f default_workflow_permissions=read -F can_approve_pull_request_reviews=true diff --git a/test/gh-aw-enlistment-skill.test.ts b/test/gh-aw-enlistment-skill.test.ts index 696212750..7d419e9c8 100644 --- a/test/gh-aw-enlistment-skill.test.ts +++ b/test/gh-aw-enlistment-skill.test.ts @@ -202,6 +202,15 @@ describe('gh-aw-enlistment skill', () => { expect(content.indexOf("issues_enabled=")).toBeLessThan(content.indexOf('gh aw add \\')); }); + it('keeps the standalone correct example fail-closed', () => { + const correctExample = content.slice(content.indexOf('### ✓ Correct:')); + expect(correctExample).toContain('if ! gh api --method PATCH "repos/${owner_repo}"'); + expect(correctExample).toContain( + 'test "$(gh api "repos/${owner_repo}" --jq \'.has_issues\')" = "true" || {', + ); + expect(correctExample).toContain('exit 1'); + }); + it('forbids blanket staging and mandates explicit paths', () => { expect(content).toMatch(/git add \.|git add -A|git commit -a/); // referenced as an anti-pattern expect(content).toContain('git add -- .gitattributes .github/aw/ .github/workflows/ .github/skills/'); @@ -269,6 +278,26 @@ describe('gh-aw-enlistment skill', () => { expect(agentGuide).toContain('bootstrap creates a research/proposals issue'); }); + it('keeps standalone public install snippets behind the Issues guard', () => { + const readme = readLF('README.md'); + const readmeInstall = readme.slice(readme.indexOf('### Install')); + expect(readmeInstall.indexOf("issues_enabled=")).toBeGreaterThan(-1); + expect(readmeInstall.indexOf("issues_enabled=")).toBeLessThan( + readmeInstall.indexOf('gh aw add \\'), + ); + expect(readmeInstall).toContain( + 'test "$(gh api "repos/${owner_repo}" --jq \'.has_issues\')" = "true" || {', + ); + + const setupSection = guide.slice( + guide.indexOf('### Enable GitHub Issues'), + guide.indexOf('### Allow workflow-created pull requests'), + ); + expect(setupSection).toContain( + 'test "$(gh api "repos/${owner_repo}" --jq \'.has_issues\')" = "true" || {', + ); + }); + it('activates slash commands only after the bootstrap PR reaches the default branch', () => { expect(guide).toContain( 'Once the bootstrap PR is merged into the default branch, the `/squad` slash', From a6a8c9574eb88d4bd344d19ab6c65a208a66bbf4 Mon Sep 17 00:00:00 2001 From: Brady Gaster Date: Thu, 24 Sep 2026 14:14:53 -0700 Subject: [PATCH 4/4] docs: deduplicate gh-aw Issues changeset Keep the fail-closed CLI and SDK release note from the review-fix commit as the single changeset for this documentation update. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com> --- .changeset/require-issues-for-gh-aw.md | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 .changeset/require-issues-for-gh-aw.md diff --git a/.changeset/require-issues-for-gh-aw.md b/.changeset/require-issues-for-gh-aw.md deleted file mode 100644 index 4a150dd7d..000000000 --- a/.changeset/require-issues-for-gh-aw.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@bradygaster/squad-cli": patch -"@bradygaster/squad-sdk": patch ---- - -Require GitHub Issues to be enabled before installing Squad Agentic Workflows, and guide authorized administrators through enabling and verifying the repository setting before bootstrap.