Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .copilot/skills/release-process/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ gh run watch
The release workflow rejects stable versions on manual dispatch, creates a
GitHub prerelease, publishes npm `preview`, and uploads standalone bundles.
It also updates the `squad-preview` Homebrew cask and
`bradygaster.Squad.Preview` WinGet package. The activation pin and insider-tag
promotion remain stable-only.
`bradygaster.Squad.Preview` WinGet package. Activation installs the latest stable
GitHub Release; insider-tag promotion also remains stable-only.

## Insider

Expand Down
163 changes: 0 additions & 163 deletions .github/workflows/squad-cli-pin-drift.yml

This file was deleted.

112 changes: 0 additions & 112 deletions .github/workflows/squad-npm-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -367,8 +367,6 @@ jobs:
contents: read
id-token: write
outputs:
# Consumed by `bump-activation-pin` so the pin moves to the version this run
# actually published, rather than to whatever npm happens to report later.
dist_tag: ${{ steps.version.outputs.dist_tag }}
stable_release: ${{ steps.version.outputs.stable_release }}
version: ${{ steps.version.outputs.version }}
Expand Down Expand Up @@ -540,116 +538,6 @@ jobs:
echo "::error::Could not verify @bradygaster/squad-cli@${PACKAGE_VERSION} on npm dist-tag '${NPM_DIST_TAG}' after 5 attempts."
exit 1

# --- Issue #1825 ------------------------------------------------------
# Release-time half of the activation-pin guard.
#
# The literal in `workflows/shared/squad.md` decides which Squad CLI a brand-new
# repository installs during activation. Nothing about publishing used to touch it,
# so every release silently made it stale — it once ran 8 days behind and was caught
# only because someone happened to cold-start a throwaway repo (PR #1818).
#
# `.github/workflows/squad-cli-pin-drift.yml` is the daily backstop that *detects*
# that state. This job is the half that prevents it, by moving the pin in the same
# run that made the new version installable. Both halves are load-bearing: detection
# alone leaves a red build with no fix path, and prevention alone re-breaks the
# moment someone publishes out-of-band.
bump-activation-pin:
name: Bump activation pin to the published release
needs: publish-cli
if: needs.publish-cli.outputs.stable_release == 'true'
runs-on: ubuntu-latest
timeout-minutes: 10
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 #v7
with:
# The pin lives on the default branch, but releases are cut from `main`.
# Bumping a `main` checkout would edit a file `dev` never sees, and the next
# merge would quietly restore the stale value.
ref: dev
fetch-depth: 0

- name: Confirm the version is published and current
id: target
env:
TARGET: ${{ needs.publish-cli.outputs.version }}
NPM_PACKAGE: '@bradygaster/squad-cli'
run: |
set -euo pipefail

if [ -z "$TARGET" ]; then
echo "::error::publish-cli reported no version — refusing to guess which version to pin."
exit 1
fi

# Two independent sources, which is the whole point of #1825: the version this
# run published, and what npm now serves as `latest`. Checking only the repo
# would compare the pin against itself, and the repo's own manifest holds the
# next *unreleased* version — the E404 that PR #1818 had to fix by hand.
latest=""
for attempt in 1 2 3 4 5; do
latest="$(npm view "$NPM_PACKAGE" dist-tags.latest 2>/dev/null || true)"
if [ "$latest" = "$TARGET" ]; then
break
fi
echo "dist-tags.latest is '${latest:-<unset>}', waiting for '$TARGET' (attempt $attempt/5)..."
sleep 15
done

if [ "$latest" != "$TARGET" ]; then
echo "::error::npm dist-tags.latest is '${latest:-<unset>}', not the published '$TARGET'. Not moving the pin to a version new repositories would not receive."
exit 1
fi

echo "version=$TARGET" >> "$GITHUB_OUTPUT"
echo "Confirmed $NPM_PACKAGE@$TARGET is the published latest."

- name: Rewrite the pin
id: bump
env:
TARGET_VERSION: ${{ steps.target.outputs.version }}
PR_BODY_FILE: ${{ runner.temp }}/activation-pin-pr.md
run: node scripts/bump-activation-pin.mjs

- name: Open pull request
if: steps.bump.outputs.changed == 'true'
env:
GH_TOKEN: ${{ github.token }}
TARGET: ${{ steps.target.outputs.version }}
PR_BODY_FILE: ${{ runner.temp }}/activation-pin-pr.md
run: |
set -euo pipefail

# A pull request rather than a push: `dev` does not take direct pushes, and a
# version bump that lands unreviewed is exactly the kind of change that should
# be visible in history.
branch="chore/activation-pin-$TARGET"

if git ls-remote --exit-code --heads origin "$branch" >/dev/null 2>&1; then
echo "Branch $branch already exists — an earlier run already opened this bump."
exit 0
fi

git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git checkout -b "$branch"

# Named explicitly: the checkout is a full release tree, and `git add -A` here
# would sweep in anything the publish jobs left behind.
git add workflows/shared/squad.md docs/src/content/docs/guide/gh-aw.md
git commit -m "chore: pin Squad CLI activation to $TARGET

Refs #1825"
git push origin "$branch"

gh pr create \
--base dev \
--head "$branch" \
--title "chore: pin Squad CLI activation to $TARGET" \
--body-file "$PR_BODY_FILE"

# --- Issues #1491 / #1497 ---------------------------------------------
# After a stable release publishes to `latest`, ensure each package's
# `insider` dist-tag is not left semver-lower than `latest`. Promotions run
Expand Down
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,19 @@ All notable changes to this project will be documented in this file.

## [Unreleased]

## [1.0.1] - 2026-10-03

### Fixed

- `squad health` now accepts casting registry persistent names as valid routing references alongside registry IDs, avoiding false unknown-agent failures (#2165).
- The immutable activation action now binds to an approved installer that fails closed on checksum-download failure, invalid checksum entries, or archive tampering, with offline pinned-installer regression coverage (#2167).

### Changed

- Root, SDK, and CLI npm versions advance together to 1.0.1 to satisfy the existing release and npm publication workflows. The CLI SDK dependency floor is now `>=1.0.1`; SDK source is unchanged from v1.0.0.
- Agentic Workflow activation installs the latest stable standalone GitHub Release by default, independently of immutable workflow/action source pins, and no longer rewrites a CLI version pin after publication (#2167).
- Consumed only the CLI health persistent-routing patch changeset. Historical changesets are unchanged; this release does not promote unrelated `dev` changes or republish `Squad.Agents.AI` NuGet 1.0.0.

## [1.0.0] - 2026-10-02

Squad CLI and SDK (the `@bradygaster/squad-cli` and `@bradygaster/squad-sdk` npm packages) graduate to 1.0.0. This is a stabilization release: there are no breaking API or command changes from 0.13.1. It marks the npm packages as stable per the project's independent per-package versioning policy (distinct from the already-stable `Squad.Agents.AI` NuGet package, which reached 1.0.0 separately in #2143).
Expand Down
23 changes: 14 additions & 9 deletions docs/src/content/docs/guide/gh-aw.md
Original file line number Diff line number Diff line change
Expand Up @@ -664,17 +664,22 @@ Once the bootstrap PR is merged into the default branch, the `/squad` slash
command is live on your repo. Pushing the bootstrap branch or merely opening the
PR does not activate the workflow.

### Optional: pin a CLI version
### CLI release selection

Activation downloads a self-contained GitHub Release bundle; it does not install
Squad from npm. Set a repository variable to select a specific standalone release:
Squad from npm. The SHA-pinned `squad-init` composite action uses its built-in
default to install the latest stable GitHub Release with mandatory checksum
verification. No repository version variable is required; existing CLI version
variables are no longer read by the shared workflow.

| Variable | Purpose | Default |
|----------|---------|---------|
| `SQUAD_CLI_VERSION` | Standalone GitHub Release tag to install during activation | `v0.13.1` |
The action runs the installer shipped at its own pinned revision. A failed
checksum download, missing or invalid checksum entry, or checksum mismatch stops
activation before extracting the archive or changing an existing CLI installation.

Set it in **Settings → Secrets and variables → Actions → Variables**. A value
without the leading `v` is accepted for compatibility with older configurations.
The CLI release is independent of `SQUAD_SHA`: workflow and action source remain
immutable, while each activation installs the current stable CLI. Direct consumers
can still select a release through the installer's `VERSION` environment variable
or the composite action's optional `version` input; the shared workflow uses neither.

### Optional: enhanced permissions with a GitHub App

Expand Down Expand Up @@ -2029,7 +2034,7 @@ Understanding the two-job architecture helps when debugging.
The activation job runs with full network access:

1. Optionally mints a GitHub App installation token
2. Resolves `SQUAD_CLI_VERSION` (default `v0.13.1`) and downloads the matching
2. Uses the pinned action's latest-release default and downloads the current stable
standalone GitHub Release bundle with checksum verification — no npm install
3. Preserves a committed team with roster entries, or runs
`squad init --preset default --state-backend local` when no usable team exists
Expand Down Expand Up @@ -2130,7 +2135,7 @@ other refs.
| A Squad label has no description and an unexpected color | It was auto-created on a fresh repo by `create-if-missing` | Expected, not a failure. Edit the label if you want a description or a specific color |
| `/squad implement` cannot create a PR | Expected under Profile A (recommended); Actions is not allowed to create pull requests and there is no automatic fallback for this workflow | Push the worker's branch and open the PR manually, or switch to [Profile B](#profile-b-opt-in-automatic-pr-creation) if you accept its repository-wide self-approval tradeoff |
| Epic implementation dispatches no workers | Every child is blocked or already has an open implementation PR | Merge dependency PRs, then run `/squad implement` on the epic again |
| Standalone activation fails before init | `SQUAD_CLI_VERSION` is invalid or its release assets are unavailable | Correct the variable or select a published release, then use **Re-run failed jobs** |
| Standalone activation fails before init | Latest stable release lookup, bundle download, or mandatory checksum verification failed | Inspect installer diagnostics and restore complete, valid release assets, then use **Re-run failed jobs** |
| Squad health fails | Initialization or committed team state is incomplete | Inspect the `Run Squad health check` JSON, correct the reported state, and rerun; no `squad-state` artifact is uploaded on failure |
| A command run was cancelled or its result is uncertain | The run stopped before a durable output was confirmed | Rerun the identical `/squad` command; Cast, implementation, activation, and review paths check existing GitHub state before creating output |

Expand Down
Loading
Loading