ci: pin npm to 11.18.0 (npm 12.0.0 broke provenance publishing)#178
Conversation
tangletools
left a comment
There was a problem hiding this comment.
🟡 Value Audit — sound-with-nits
| Verdict | sound-with-nits |
| Concerns | 2 (2 weak-concern) |
| Heuristic | 0.0s |
| Duplication | 0.0s |
| Interrogation | 80.8s (2 bridge agents) |
| Total | 80.8s |
💰 Value — sound-with-nits
Pins the two npm install -g npm@latest calls in publish.yml to a known-good npm@11.18.0 so npm 12.0.0's broken --provenance/sigstore path stops failing OIDC publishes — a correct, in-grain fix with only a trivial DRY nit.
- What it does: Replaces the floating
npm install -g npm@latestwithnpm install -g npm@11.18.0at.github/workflows/publish.yml:63(auto-release job) and:155(tag publish-npm job), adding a comment at each site explaining npm 12.0.0 (2026-07-08) broke--provenancewithMODULE_NOT_FOUND: sigstoreand to revisit once a fixed 12.x ships. Behavior delta: publishes resolve to a deterministic npm instead - Goals it achieves: Restores the publish pipeline that npm 12.0.0 broke, while keeping OIDC trusted publishing +
--provenance(11.18.0 ≥ the 11.5.1 OIDC floor noted at publish.yml:147). Eliminates a non-deterministic, supply-chain-mutable input (@latest) from the release path so releases are reproducible, and records the pin's rationale + sunset condition inline so it doesn't silently rot. Confirmed against the r - Assessment: Good on its merits. It's the smallest change that fixes the actual failure (the tool version, not repo code), it lives in the single file the repo has already designated as the sole publish origin (publish.yml:3-12), and it follows the workflow's existing heavily-commented style. The diagnosis (floating
@latestgrabbed a broken upstream) matches the evidence: prior commit HEAD^ hadnpm@latest - Better / existing approach: none materially better. Checked for existing mechanisms to reuse: no
.github/dependabot.yml, norenovate.json, no shared composite action for the npm install — so there is nothing to extend instead of reinvent. A global npm upgrade is genuinely required (Node 22 ships npm 10.x, below the 11.5.1 OIDC floor per publish.yml:147), so corepack/packageManager-pinning can't replace it. The PR's own s - Model: opencode/kimi-for-coding/k2p7
- Bridge attempts: 1
🎯 Usefulness — sound-with-nits
Correct, well-scoped pin that restores a confirmed-broken publish path (0.43.15 is provably missing from npm); both npm-install sites are covered and the fix self-triggers on merge.
- Integration: Fully integrated and immediately reachable: publish.yml is the only publish workflow, the auto-release job fires on every push to main (publish.yml:14-16,28-31), so merging this PR itself triggers a pinned-npm release of 0.43.16. Both npm@latest occurrences were replaced (grep confirms exactly 2 matches, both 11.18.0, zero @latest left). ci.yml publishes nothing, so there is no uncovered path.
- Fit with existing patterns: Fits the established pattern exactly. The workflow already deliberately upgraded npm as a named step to satisfy OIDC's npm>=11.5.1 requirement (publish.yml:147); pinning that same step is the natural, in-grain evolution — no competing or duplicate pattern introduced. Comments preserve the existing reasoning and add the pin rationale + revisit trigger.
- Real-world viability: Holds up: pin precedes both
npm version(publish.yml:69) andnpm publish --provenance(publish.yml:79,169), so broken npm 12 is never invoked; idempotent skip-on-already-published guards re-runs and the stuck v0.43.15 tag (publish.yml:76,166); 11.18.0 satisfies the >=11.5.1 OIDC floor. Registry evidence (0.43.14 latest, 0.43.15 absent) independently confirms the breakage this fixes is real and - Model: opencode/zai-coding-plan/glm-5.2
- Bridge attempts: 1
💰 Value Audit
🟡 npm version literal is duplicated at two sites in one file [maintenance] ``
npm@11.18.0is hardcoded at both publish.yml:63 and publish.yml:155 with near-identical rationale comments. When a fixed npm 12.x ships, both must be bumped in sync or the two publish paths diverge. Cheap fix: hoist to a workflow-levelenv: NPM_VERSION: 11.18.0and runnpm install -g npm@$NPM_VERSION. Does not gate shipping — the duplication already existed as@latest— but it is the one place rot could re-enter.
🎯 Usefulness Audit
🟡 Exact pin vs npm@^11 — a range would auto-track 11.x security patches while still blocking the 12.x break [problem-fit] ``
npm install -g npm@npm@11.18.0(publish.yml:63,155) is reproducible but will silently miss any future 11.x security/fix release until a human manually bumps it.npm install -g npm@^11resolves to >=11.0.0 <12.0.0, so it would have avoided this npm-12 break automatically AND would keep pulling 11.x patches — at the cost of minor cross-run drift. The PR body's reproducibility/supply-chain argument for an exact pin is legitimate, so this is a genuine judgment call, not a defect; worth a human w
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 —
|
| deepseek | kimi-code | aggregate | |
|---|---|---|---|
| Readiness | 95 | 89 | 89 |
| Confidence | 65 | 65 | 65 |
| Correctness | 95 | 89 | 89 |
| Security | 95 | 89 | 89 |
| Testing | 95 | 89 | 89 |
| Architecture | 95 | 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.
🟡 LOW Temporary pin has no tracking or auto-bump path — .github/workflows/publish.yml
The comment says 'Revisit once a fixed 12.x ships' but there is no linked tracking issue and no Dependabot/Renovate coverage for the globally-installed npm CLI, so the pin can linger after upstream lands a fix. A pinned global tool also will not auto-receive npm security patches (mitigated here because 11.18.0 is only ~10 days old and is still the
next-11dist-tag). Non-blocking: open a tracking issue and/or add an ecosystem entry so the pin is revisited when a fixed 12.x (>=12.0.1) is published.
🟡 LOW npm version literal duplicated across two jobs — .github/workflows/publish.yml
npm install -g npm@11.18.0is hard-coded in both the auto-release job (L60-63) and the publish-npm job (L153-155), each with its own near-duplicate rationale comment. They match today, but there is no single source of truth; a future bump that edits one site and not the other would make the auto-release and tag-publish paths run different npm CLIs with different provenance/OIDC behavior. Fix (non-blocking): hoist to a job/workflowenv(e.g.NPM_CLI_VERSION: '11.18.0') or a YAML anchor and reference it in bothnpm install -g npm@${{ env.NPM_CLI_VERSION }}steps.
tangletools · 2026-07-09T10:08:18Z · trace
tangletools
left a comment
There was a problem hiding this comment.
✅ Approved — 2 non-blocking findings — 58df893c
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-09T10:08:18Z · immutable trace
Summary
Pin the CI npm version instead of installing
npm@latest.Why
npm@12.0.0(published 2026-07-08 21:06 UTC) brokenpm publish --provenance— its provenance path fails withMODULE_NOT_FOUND: Cannot find module 'sigstore'. Because the workflow rannpm install -g npm@latest, every publish after that date silently grabbed the broken npm 12 and failed. Nothing in this repo changed — npm did.Last known-good publishes used npm 11.18.0 (the last 11.x, ≥ 11.5.1 so OIDC trusted publishing + provenance still work). This pins to it.
Best-practice notes
@latestin a publish pipeline is non-deterministic + a supply-chain risk; pinning makes releases reproducible.--provenance+ OIDC trusted publishing are kept — those are the good parts; only the npm version was the problem.Effect on merge
Pushing this to
maintriggers auto-release with pinned npm → bumps0.43.15 → 0.43.16and publishes it. (0.43.15was bumped/tagged but never reached npm due to the npm 12 bug; it is skipped, and this also sidesteps the stuckv0.43.15tag.) Bothnpm install -g npm@latestoccurrences (auto-release + tag paths) are pinned.