Filed by the PM dispatch loop as option B of an open question the #15990 round left for decision (its report, and PR #16009). ⛔ Unassigned and ungraded — domain:*, type and priority are triage's.
⚠️ Framed honestly: this is defence in depth against a channel whose only known trigger has just been removed. The round that found it recommended A — leave it, and its reasoning is sound and measured. This card exists because the realised cost of the channel firing was high, not because the round was wrong. A maintainer who agrees with A should close this cheaply.
The channel
.github/actions/setup-pnpm caches COREPACK_HOME with actions/cache@v6 — the full cache action, not cache/restore. So the post-job save writes back whatever any step materialised into that store, including a package manager nobody pinned.
That is what fired today. Measured by the #15990 round:
setup-pnpm materialises only the pinned pnpm 10.31.0 and writes no lastKnownGood.json.
check-regen-pending.mjs --self-test ran a stub gate in a tmpdir() that pins nothing, so Corepack resolved pnpm's latest from the registry — measured, it downloaded 12.3.4.
- pnpm 12's Rust CLI rejects
-s with exit 2, so every stub read as "gate exited non-zero" ⇒ stale, reddening exactly the cases expecting a non-stale verdict.
- Corepack wrote
lastKnownGood.json, which is sticky, and cache@v6 saved that store back. Subsequent jobs then restored a store holding either a -s-accepting pnpm (green) or a pnpm 12 (red).
That is why the failure was flaky ACROSS jobs but byte-identical WITHIN one — a fact a plain "the launcher sometimes fails to resolve" story cannot account for.
Realised cost, so the priority is judged on evidence
On 2026-09-05 this reddened origin/main's own push build (run 33981169123, event=push, concluded failure at 17:51Z) and four unrelated PRs — #15980, #15996, #15978, #15998 — three of which were otherwise complete and correct. It cost a PM cycle per PR and pointed each seat at its own innocent diff.
Why the round recommended A, stated fully rather than summarised
After #16009, nothing in scripts/ spawns a package manager outside the repo any more, so the channel has no trigger. The round measured this with a positively-controlled grep (the pattern fires on exactly the pre-fix line the defect was about), leaving three sites, none exposed: scripts/pm/dispatch-gates.mjs:18541 is a string literal inside a self-test corpus and never executed; both scripts/qa/log-volume-census.mjs sites run with cwd: repoRoot where the pin applies, in a tool no workflow invokes.
What B would be
Make the store unable to hold an unpinned package manager, so the channel cannot be re-armed by the next fixture that shells out:
- switch to
actions/cache/restore so a job cannot write the store back, or
- assert after setup that the store holds only the pinned version, failing loudly if not.
⚠️ Verify the mechanism before implementing — it is one round's measurement. In particular re-measure that setup-pnpm writes no lastKnownGood.json and that cache@v6 (not cache/restore) is what the action uses today; ⛔ a hardening that misreads the current action would be worse than none.
Refs
#15990 / PR #16009 (the fix that removes today's trigger) · #9258 (prior art in the same fixture: an environment-dependent flake fixed by removing the dependence rather than retrying) · #15980 · #15996 · #15978 · #15998 (the four PRs it reddened)
Generated by Claude Code
Filed by the PM dispatch loop as option B of an open question the #15990 round left for decision (its report, and PR #16009). ⛔ Unassigned and ungraded —
domain:*, type and priority are triage's.The channel
.github/actions/setup-pnpmcachesCOREPACK_HOMEwithactions/cache@v6— the full cache action, notcache/restore. So the post-job save writes back whatever any step materialised into that store, including a package manager nobody pinned.That is what fired today. Measured by the #15990 round:
setup-pnpmmaterialises only the pinned pnpm 10.31.0 and writes nolastKnownGood.json.check-regen-pending.mjs --self-testran a stub gate in atmpdir()that pins nothing, so Corepack resolved pnpm'slatestfrom the registry — measured, it downloaded 12.3.4.-swith exit 2, so every stub read as "gate exited non-zero" ⇒stale, reddening exactly the cases expecting a non-stale verdict.lastKnownGood.json, which is sticky, andcache@v6saved that store back. Subsequent jobs then restored a store holding either a-s-accepting pnpm (green) or a pnpm 12 (red).That is why the failure was flaky ACROSS jobs but byte-identical WITHIN one — a fact a plain "the launcher sometimes fails to resolve" story cannot account for.
Realised cost, so the priority is judged on evidence
On 2026-09-05 this reddened
origin/main's own push build (run33981169123,event=push, concluded failure at 17:51Z) and four unrelated PRs — #15980, #15996, #15978, #15998 — three of which were otherwise complete and correct. It cost a PM cycle per PR and pointed each seat at its own innocent diff.Why the round recommended A, stated fully rather than summarised
After #16009, nothing in
scripts/spawns a package manager outside the repo any more, so the channel has no trigger. The round measured this with a positively-controlled grep (the pattern fires on exactly the pre-fix line the defect was about), leaving three sites, none exposed:scripts/pm/dispatch-gates.mjs:18541is a string literal inside a self-test corpus and never executed; bothscripts/qa/log-volume-census.mjssites run withcwd: repoRootwhere the pin applies, in a tool no workflow invokes.What B would be
Make the store unable to hold an unpinned package manager, so the channel cannot be re-armed by the next fixture that shells out:
actions/cache/restoreso a job cannot write the store back, orsetup-pnpmwrites nolastKnownGood.jsonand thatcache@v6(notcache/restore) is what the action uses today; ⛔ a hardening that misreads the current action would be worse than none.Refs
#15990 / PR #16009 (the fix that removes today's trigger) · #9258 (prior art in the same fixture: an environment-dependent flake fixed by removing the dependence rather than retrying) · #15980 · #15996 · #15978 · #15998 (the four PRs it reddened)
Generated by Claude Code