fix(release): pin npm 11 for provenance publish#28
Conversation
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — 00da486f
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-09T22:04:48Z
✅ No Blockers —
|
| opencode-kimi | glm | deepseek | aggregate | |
|---|---|---|---|---|
| Readiness | 89 | 92 | 95 | 89 |
| Confidence | 65 | 65 | 65 | 65 |
| Correctness | 89 | 92 | 95 | 89 |
| Security | 89 | 92 | 95 | 89 |
| Testing | 89 | 92 | 95 | 89 |
| Architecture | 89 | 92 | 95 | 89 |
Reviewer score is advisory once the run is complete and the verdict has no blockers.
Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision.
🟡 LOW Floating major pin (npm@11) leaves release reproducibility exposed to future 11.x regressions — .github/workflows/release.yml
npm install -g npm@11resolves to the latest 11.x at run time. If a future 11.x patch reintroduces a provenance/sigstore issue, releases break silently with no code change. Pinning to an exact version (e.g. npm@11.5.1, matching the documented OIDC floor) would make the release environment fully reproducible and force an intentional bump. Low severity — current behavior is correct; this is a hardening nit.
🟡 LOW No upstream link / revisit TODO for the npm 12 pin — .github/workflows/release.yml
The comment documents the npm 12.0.0 sigstore/provenance regression as the reason for the pin, but does not link the upstream npm/cli issue or note the second concrete blocker visible in the v12.0.0 release notes: npm 12 requires Node ^22.22.2 || ^24.15.0 || >=26.0.0 while this workflow pins
node-version: 22. Add an issue link and a short TODO to revisit the pin (and bump Node) once npm 12 provenance is confirmed working, so the workaround does not silently fossilize. Documentation/operational nit only; no functional defect.
🟡 LOW Pin still floats within npm major; consider exact version for fully reproducible releases — .github/workflows/release.yml
npm install -g npm@11resolves to the latest 11.x (currently 11.18.0). This is strictly better thannpm@latest, but it is the same class of floating-version risk at the patch level — a future 11.x patch could in principle regress the provenance publish path the same way 12.0.0 did. For a release pipeline, prefer an exact immutable pin (e.g.npm@11.18.0), optionally paired with a checksum, so every release runs an identical npm. Impact is low: the OIDC requirement (>= 11.5.1) remains satisfied and provenance works today.
tangletools · 2026-07-09T22:06:52Z · trace
tangletools
left a comment
There was a problem hiding this comment.
🟢 Value Audit — sound
| Verdict | sound |
| Concerns | 0 (none) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 103.4s (2 bridge agents) |
| Total | 103.4s |
💰 Value — sound
One-line pin of the release workflow from npm@latest to npm@11 (with a precise why-comment) to unbreak provenance publishing that npm 12.0.0 regressed — a minimal, in-grain, correct fix with no better design available.
- What it does: Changes
.github/workflows/release.yml:28fromnpm install -g npm@latesttonpm install -g npm@11, and updates the preceding comment (lines 26-27) to record the npm 12.0.0 sigstore regression and the npm >=11.5.1 OIDC floor. Behaviorally the release job now resolves the latest npm 11.x instead of whateverlatestpoints at, so thechangesets/action@v1publish step (line 29, with `NPM_CONFI - Goals it achieves: Unblock the release pipeline: the prior run installed npm 12.0.0 via
@latestand all 8 package publishes failed withMODULE_NOT_FOUND: Cannot find module sigstorefromlibnpmpublish/lib/provenance.js. After merge, OIDC trusted publishing + provenance (the workflow's whole purpose, per theid-token: writeat line 16 and provenance env at line 37) works again on a known-good major, and the c - Assessment: Good on its merits. It is the smallest possible change, sits directly on the line that was just introduced in
b1e51ab ci: use npm OIDC trusted publishing with provenance for releases, targets the observed failure precisely, keeps the OIDC version floor satisfied, and documents the constraint inline. The author is appropriately honest that the real proof is the post-merge run (no fake fallback to - Better / existing approach: none — this is the right approach. Searched:
.github/workflows/contains onlyci.ymlandrelease.yml;git grep 'npm install -g'andgit grep -i provenance|sigstore|id-tokenreturn onlyrelease.yml, so there is no second publisher in this repo to reuse or keep in sync (the PR's 'agent-eval publisher' reference is cross-repo prior art, not local). Considered and rejected alternatives: pi - Model: opencode/kimi-for-coding/k2p7
- Bridge attempts: 1
🎯 Usefulness — sound
Pins the release workflow's npm to major 11 to dodge the npm 12.0.0 sigstore/provenance regression — a minimal, correct fix matching a known-good org pattern.
- Integration: The step sits directly in the release job's critical path at
.github/workflows/release.yml:28, running on every push tomain(lines 3-5) right beforechangesets/action@v1publishes (line 29). Fully reachable; no new surface introduced. - Fit with existing patterns: Consistent with the existing pattern — the workflow already ran a global npm install at this exact step (just
npm@latestbefore). The PR body notes the samenpm@11pin is already known-good in the agent-eval publisher, so it matches an established org convention rather than inventing one. - Real-world viability: Floating within major 11 (
npm@11) deliberately gets security/patch updates while excluding the breaking 12.x provenance path — the right granularity, not a stale exact pin. npm 11 always satisfies the>= 11.5.1OIDC requirement cited in the comment, so the constraint holds over time. - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
No concerns — sound change, no better or existing approach found. ✅
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 3 non-blocking findings — 00da486f
Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-07-09T22:06:52Z · immutable trace
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — be74228d
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-09T22:14:48Z
tangletools
left a comment
There was a problem hiding this comment.
🟢 Value Audit — sound
| Verdict | sound |
| Concerns | 0 (none) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 59.8s (2 bridge agents) |
| Total | 59.8s |
💰 Value — sound
Pins the release workflow's global npm to the exact known-good 11.18.0 instead of floating npm@latest, fixing the npm 12 sigstore/MODULE_NOT_FOUND provenance failure — minimal, in-grain, no better approach found.
- What it does: In .github/workflows/release.yml:28, replaces
npm install -g npm@latestwithnpm install -g npm@11.18.0and updates the comment (lines 26-27) to document the npm 12.0.0 sigstore omission and the OIDC >=11.5.1 floor. The pinned npm is whatpnpm changeset:publish(line 32) shells out to for the OIDC/provenance publish (NPM_CONFIG_PROVENANCE true, line 37). The branch's tip be74228 already tigh - Goals it achieves: Unblock the failing 0.20.0 release: npm@latest resolved to 12.0.0 whose libnpmpublish/provenance.js drops the sigstore module, breaking all 8 package publishes. Pinning to the known-good 11.x restores tokenless OIDC trusted publishing + provenance on node 22 (which ships an older npm) and prevents the next npm major from silently re-breaking the same path.
- Assessment: Good on its merits. It is the smallest lever that addresses the root cause (the npm CLI version changesets invokes), matches the existing grain of the workflow (just a version string + explanatory comment), and the exact-pin form in be74228 is strictly better than the floating
npm@11it supersedes because it removes the very drift that caused the incident. - Better / existing approach: none — this is the right approach. Searched the repo: only two workflows exist (release.yml, ci.yml); ci.yml does not publish; there is no shared/composite action and no other
npm install -g/provenance usage to reuse or centralize (the agent-eval publisher referenced in the body lives in another repo). The realistic alternatives are worse: bumping to node 24 for a newer bundled npm is a far larg - Model: opencode/kimi-for-coding/k2p7
- Bridge attempts: 1
🎯 Usefulness — sound
Pin the release workflow's npm to 11.18.0 to stop npm 12's broken provenance path from failing every publish — the minimal correct fix for the actual broken release.
- Integration: Fully reachable: this step IS the only publish path, running before changesets/action on every push to main (release.yml:4,28); not new surface, just a narrowed version on the existing bump-npm step.
- Fit with existing patterns: Matches the established pattern — the file already bumped npm for OIDC provenance (release.yml:15-16,26); this just replaces the unsafe @latest (which rolled to broken npm 12.0.0) with a pinned known-good version, the standard fix.
- Real-world viability: Holds up: a hard pin is more reproducible than @latest/@11 and avoids the exact class of break that motivated it; only minor trade-off is no auto-uptake of future 11.x patches, acceptable for a release pipeline.
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
No concerns — sound change, no better or existing approach found. ✅
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
✅ No Blockers —
|
| opencode-kimi | glm | deepseek | aggregate | |
|---|---|---|---|---|
| Readiness | 92 | 89 | 89 | 89 |
| Confidence | 65 | 65 | 65 | 65 |
| Correctness | 92 | 89 | 89 | 89 |
| Security | 92 | 89 | 89 | 89 |
| Testing | 92 | 89 | 89 | 89 |
| Architecture | 92 | 89 | 89 | 89 |
Reviewer score is advisory once the run is complete and the verdict has no blockers.
Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision.
🟡 LOW Comment claim about sigstore omission is imprecise — .github/workflows/release.yml
The comment states 'npm 12.0.0 omits sigstore from its provenance publish path.' Verified that sigstore is still present in npm 12.0.0's dependency tree: libnpmpublish@12 depends on sigstore@^5.0.0, and npm@12.0.0 depends on @sigstore/tuf@^5.0.0. The claim likely refers to a runtime code-path regression (sigstore not being invoked during provenance signing) rather than dependency removal, but the comment as written says 'omits sigstore' which is factually inaccurate at the dependency level. Suggest rewording to something like 'npm 12.0.0 has a regression in its sigstore-based provenance signing path' to avoid misleading future maintainers who grep the dep tree.
🟡 LOW Comment rationale rests on a single claim; consider also citing npm 12's broader breaking changes — .github/workflows/release.yml
The new comment (lines 26-27) justifies the pin solely as 'npm 12.0.0 omits sigstore from its provenance publish path.' The official v12.0.0 release notes (github.com/npm/cli/releases/tag/v12.0.0) enumerate many breaking changes but do not explicitly name a provenance/sigstore removal, and
npm viewshows @sigstore/tuf is still bundled in both 11.18.0 (^4.0.2) and 12.0.0 (^5.0.0). I could not independently disprove the sigstore claim (the real behavior lives in libnpmpublish@12), so this is not a correctness bug — but the pin is more defensibly justified by also citing npm 12's documented breaking changes that can break this pipeline (node engine now ^22.22.
🟡 LOW Hardcoded npm version will rot without automation — .github/workflows/release.yml
Pinning npm@11.18.0 is correct for now (npm 12.0.0 broke sigstore), but this hardcoded version won't receive security fixes for npm itself. Consider adding a dependabot config entry or a scheduled action that opens a PR when a newer npm 11.x patch is available. Currently no mechanism keeps this version current.
🟡 LOW No assertion that pinned npm is active before publish — .github/workflows/release.yml
After
npm install -g npm@11.18.0, the workflow proceeds directly to changesets/action which invokes npm publish. If the global install fails silently or npm 11.18.0 is yanked from the registry, the publish would fall back to whatever npm version Node 22 ships, which is < 11.5.1 and may break OIDC provenance. Addnpm --versionafter the install to fail fast with a readable error.
🟡 LOW No automated update mechanism for pinned npm version — .github/workflows/release.yml
Pinning to exact npm@11.18.0 improves reproducibility but means security patches to the npm 11.x line (e.g., 11.18.1 for a vuln fix) will require manual intervention. No Dependabot/Renovate config was found in the repo to alert on outdated pins. Consider adding a dependabot.yml entry for github-actions (or a periodic scheduled check) so stale pins surface automatically. Not a blocker — manual bumps are acceptable for a release workflow where reproducibility is the priority.
tangletools · 2026-07-09T22:18:28Z · trace
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 5 non-blocking findings — be74228d
Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-07-09T22:18:28Z · immutable trace
tangletools
left a comment
There was a problem hiding this comment.
✅ Auto-approved drewstone PR — a93fc4da
This PR was opened by the trusted drewstone account.
The full PR reviewer audit still runs separately and will publish findings if it detects issues.
tangletools · auto-approval · reason: drewstone_author · 2026-07-09T22:20:01Z
✅ No Blockers —
|
| opencode-kimi | glm | deepseek | aggregate | |
|---|---|---|---|---|
| Readiness | 92 | 95 | 95 | 92 |
| Confidence | 65 | 65 | 65 | 65 |
| Correctness | 92 | 95 | 95 | 92 |
| Security | 92 | 95 | 95 | 92 |
| Testing | 92 | 95 | 95 | 92 |
| Architecture | 92 | 95 | 95 | 92 |
Reviewer score is advisory once the run is complete and the verdict has no blockers.
Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision.
🟡 LOW Pin will need a manual bump once npm 12.x fixes provenance — .github/workflows/release.yml
npm@11.18.0 is currently the head of the 11.x line (registry shows no 11.19.0;
latest= 12.0.0). The hard pin is correct today, but once a 12.x release resolves the sigstore MODULE_NOT_FOUND provenance bug, staying pinned on 11.18.0 will miss upstream fixes until someone manually bumps it. The inline comment documents the trigger condition, which mitigates this; consider a follow-up tracking issue or a periodic check. Not a merge blocker.
tangletools · 2026-07-09T22:23:50Z · trace
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 1 non-blocking finding — a93fc4da
Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision. | Full multi-shot audit completed 1/1 planned shots over 1 changed files. Global verifier still owns final merge decision.
Full immutable report for this review: trace
Summary comment for this run: full summary
tangletools · 2026-07-09T22:23:50Z · immutable trace
tangletools
left a comment
There was a problem hiding this comment.
🟡 Value Audit — sound-with-nits
| Verdict | sound-with-nits |
| Concerns | 1 (1 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 159.9s (2 bridge agents) |
| Total | 159.9s |
💰 Value — sound-with-nits
Pins the release publisher to npm 11.18.0 (with a hard version assertion) instead of floating npm@latest, fixing the npm 12 provenance breakage — coherent and in-grain, with only a tiny single-source nit.
- What it does: In .github/workflows/release.yml:29-31, replaces
npm install -g npm@latestwithnpm install -g npm@11.18.0followed bytest "$(npm --version)" = "11.18.0". Behavior delta: the release job no longer tracks the moving npm major; it installs an exact known-good npm and fails the step loudly if that version is not what actually got installed. - Goals it achieves: Unbreaks OIDC trusted publishing with provenance. npm 12.0.0 (pulled by npm@latest) ships a broken provenance path — libnpmpublish/lib/provenance.js throws MODULE_NOT_FOUND for
sigstore— which is what failed all 8 publishes in the 0.20.0 run (job 86026974437). npm 11.18.0 clears the OIDC >=11.5.1 floor and is the known-good version; the assertion turns the pin into a self-enforcing invariant so - Assessment: Good change, built in the grain. The repo already pins every release input hermetically — packageManager pnpm@10.23.0 (package.json:6), pnpm install --frozen-lockfile (release.yml:25), pinned action SHAs/versions — so
npm@latestwas the lone non-hermetic input and it is exactly the thing that broke. Pinning + asserting matches that reproducibility posture. ci.yml (ci.yml:1-21) never invokes npm, - Better / existing approach: none materially better. Searched for an existing equivalent to reuse: grep
npm install -g npmhits only release.yml:30; .github/ contains only workflows/ (no reusable/composite actions); packageManager pins pnpm, not npm, and npm does not reliably self-pin from engines during a global install, so the explicit install+assert is the robust path. Extracting a shared action would have exactly one co - Model: opencode/kimi-for-coding/k2p7
- Bridge attempts: 1
🎯 Usefulness — error
usefulness agent produced no parseable value-audit JSON.
- Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
- Bridge error: no parseable JSON response
💰 Value Audit
🟡 Version literal repeated in three places [maintenance] ``
11.18.0now appears in the install spec (release.yml:30), the assertion string (release.yml:31), and the comment (release.yml:26-28). A future bump must keep all three in sync; single-sourcing via one env var (e.g.NPM_VERSION=11.18.0→npm install -g npm@$NPM_VERSIONandtest "$(npm --version)" = "$NPM_VERSION") removes the drift window. Minor and arguably the repetition is good defense-in-depth, so it does not gate shipping.
What this audit checks
It judges the change on its merits — not whether it was tasked out in an issue. Unticketed, fast-moving work is fine; the question is whether the change is good and whether a better or existing approach should be used instead.
| Pass | What it asks |
|---|---|
| Heuristic | Vague title? Whitespace-only or cruft-bearing diff? (content signals only) |
| Duplication | Do added function/class names already exist elsewhere in the repo? |
| Value Audit | What does it do? What goal does it achieve? Is it good? Better architecture or already-exists? |
| Usefulness Audit | Does it integrate and fit? Will it hold up in real use and actually get used? |
Findings are concerns, not blocks — the human reviewer decides what to do with them.
What changed
Pin the release workflow to npm 11 instead of
npm@latest.The failed 0.20.0 release installed npm 12.0.0, then every package publish failed with
MODULE_NOT_FOUND: Cannot find module sigstorefromlibnpmpublish/lib/provenance.js. npm 11 satisfies the OIDC requirement and is the known-good version already used by the agent-eval publisher.Verification
86026974437directly: all 8 package publishes failed on the same npm 12 provenance errorgit diff --checkorigin/mainThe real proof is the post-merge release run publishing 0.20.0; no token fallback is added.