Repository navigation
Description
Problem
The gh-aw activation workflow pins SQUAD_CLI_VERSION to a fixed released version. That pin decays silently with every npm release and there is no mechanism that detects it.
Evidence
- Pin introduced 2026-08-07 in
60032b5b, referencing0.11.0. It was correct that day —v0.11.0published 2026-06-30, andv0.12.0did not exist yet. v0.12.0published 2026-08-13. The pin became stale with nobody touching it.git log -Sshows the pin line has been modified exactly once, ever — at introduction.- It ran 8 days undetected and was caught only because an agent chose to run a cold start against a throwaway repo. Fixed manually in PR fix(gh-aw): bump activation CLI pin 0.11.0 → 0.12.0 (new-repo readiness) #1818.
This is structural decay, not sloppiness: every release silently re-breaks new-repo activation.
Why a fixed pin is still correct
Activation runs on an unrestricted-network job and hands state to the sandboxed agent job. A bad point release mid-hop is expensive to debug. Reproducibility argues for pinning. The pin is not the problem — the absence of a drift mechanism is.
⚠️ Trap for whoever implements this
Do NOT derive the pin from in-repo packages/squad-cli/package.json. It currently reads 0.13.0 — an unpublished version that resolves to E404 on npm, with 3 pending unmerged changesets. Automating from it would drive straight into the exact failure PR #1818 just fixed.
A guard must compare two independent sources: the workflow file's pin versus the highest published release tag (or npm dist-tags). Anything that reads the thing it guards is decoration, per .squad/decisions.md:604.
Current npm state for reference: dist-tags = { latest: 0.12.0, insider: 0.12.0, preview: 0.8.17-preview }.
Suggested direction
- Release-time bump — the release flow updates the pin as part of publishing.
- CI guard as backstop — compare pin against highest published release tag; fail if behind. This catches the case where (1) is skipped or a release happens out-of-band.
Both are wanted. (1) alone reintroduces the failure whenever someone releases manually; (2) alone leaves a red build with no fix path.
Note
The pin was one minor version behind (0.11.0 vs published 0.12.0), not two. The in-repo 0.13.0 is unpublished and does not count.
Owners
FIDO (CI guard) with EECOM (release flow).
Activity
bradygaster commentedon Aug 23, 2026
1. Owner & rationale
Owner:
squad:surgeon. This is release hygiene around the activation CLI pin; Surgeon owns release-manager flow, with Booster as CI backstop reviewer.Labels reconciled as:
gh-aw,type:bug,priority:p1,wave:1-next,squad:surgeon,triaged,go:spec-ready.2. Files in scope
Verified existing paths:
workflows/shared/squad.md.github/workflows/squad-release.yml.github/workflows/squad-standalone-release.ymltemplates/workflows/squad-release.ymltest/release.test.tstest/promote-insider-tag.test.tstest/publish-policy.test.ts3. Reproduction / measurement
These commands were execution-tested and use no output suppression:
They show the activation fallback pin in
workflows/shared/squad.mdand the currently published npm dist-tags to compare it against.4. Verification bar
A CI/release guard must compare the workflow pin against the highest published npm release/dist-tag and fail when the pin lags. The guard must fail if
workflows/shared/squad.mdis pinned below publishedlatest, and pass when the pin equals the intended published stable version.5. Traps
Do not read
packages/squad-cli/package.jsonas the target version. It currently reads0.13.0, which is unpublished;npm view @bradygaster/squad-cli@0.13.0 versionreturns E404. The guard must compare the workflow pin against the highest published npm release / dist-tag, not an in-repo pre-release workspace version.6. Out of scope
Do not switch activation to an unpinned install, change the package versioning policy, or make broad release-template refactors. Keep the fix to release-time pin maintenance plus a drift guard.
7. Session-stall guard
fix(ci): scope an SC2016 suppression and restore its coverage by test
ci: add a daily drift guard for the Squad CLI activation pin (#1855)
bradygaster commentedon Aug 24, 2026
Half of this shipped in #1855 (merged). Leaving this open for the other half.
Measured first: the pin is
0.12.0and npmdist-tags.latestis0.12.0— they already agree, so there was nothing to bump. This issue was never really about a stale number; it was about there being no mechanism to notice when it does go stale.Shipped:
.github/workflows/squad-cli-pin-drift.yml— daily 07:15 UTC +workflow_dispatch. Extracts the pin, compares to npmdist-tags.latest, files a de-duplicated issue and fails on drift.test/squad-cli-pin.test.ts— offline self-consistency: the header comment and theenv:literal cannot disagree, and the guard must read npm rather than the in-repo manifest.workflows/shared/squad.md:90.${SQUAD_CLI_VERSION:-0.12.0}could never fire, becausevars.X || '0.12.0'always yields a non-empty value. A bare${SQUAD_CLI_VERSION}now fails loudly instead of silently masking an empty pin.The trap worth recording: the in-repo
packages/squad-cli/package.jsonsays0.13.0, which is unpublished and E404s on npm. Deriving the pin from it reproduces exactly the failure PR #1818 fixed. The drift guard therefore reads npm, and a test enforces that it keeps doing so.Still open — the release-time half. Nothing moves the pin as part of publishing. The daily guard is a backstop: it catches drift the morning after, not at the moment it is introduced. Closing this issue now would claim a release-time guarantee that does not exist.
Also of note for whoever picks this up: CI lints with shellcheck 0.10.0 pinned, and
actionlintsilently skips its shellcheck integration when shellcheck is absent from PATH. A local lint can therefore pass while CI fails — it did here (SC2016 on the markdown backticks in the issue-bodyprintfblock). Install shellcheck 0.10.0 locally before trusting a clean local run.ci: move the Squad CLI activation pin when the release publishes (git…
chore: pin Squad CLI activation to 1.0.0