Skip to content

ci: use npm ci over npm install, pin npm CLI, move audit earlier - #21

Merged
mizcausevic-dev merged 2 commits into
mainfrom
ci/use-npm-ci
Sep 13, 2026
Merged

mizcausevic-dev merged 2 commits into
mainfrom
ci/use-npm-ci

Conversation

@mizcausevic-dev

Copy link
Copy Markdown
Owner

Summary

Branch 0 of the agent-trace-normalizer review's fix plan (highest leverage, lowest cost, ships alone and non-breaking).

  • publish.yml: npm install -g npm@latest -> npm install -g npm@11.5.1 --ignore-scripts (the file's own comment already names 11.5.1 as the requirement)
  • publish.yml and ci.yml: npm install -> npm ci --ignore-scripts against the committed, audited lockfile
  • npm audit --audit-level=high added to publish.yml (was absent) and moved to run immediately after install in ci.yml (was last, after everything else already passed)

This job holds id-token: write right before npm publish --provenance. npm install re-resolves every ^-range dependency against whatever currently satisfies it on the registry at publish time, bypassing the audited lockfile entirely. npm ci pins to exactly what's committed.

Deliberately deferred: SHA-pinning actions/checkout/setup-node/codeql-action, and an environment: npm-publish approval gate. Real hygiene, but defend against GitHub/npm Inc. itself being compromised rather than this repo's actual threat model, and the environment gate needs a GitHub Environment created first (repo settings, not code).

Test plan

  • npm ci --ignore-scripts — 194 packages, 0 vulnerabilities
  • npm run lint
  • npm run typecheck
  • npm run coverage — 24/24 tests
  • npm run build
  • npm run demo

🤖 Generated with Claude Code

mizcausevic-dev and others added 2 commits September 13, 2026 17:47
publish.yml previously ran npm install -g npm@latest (unpinned mutable
tag) then npm install (ignoring the committed lockfile) in a job that
holds id-token: write immediately before npm publish --provenance. A
compromised transitive dependency resolved fresh at publish time would
get a valid provenance attestation. Pins the npm CLI to the version
the file's own comment already names (11.5.1), switches both
publish.yml and ci.yml to npm ci --ignore-scripts against the audited
lockfile, and adds/moves npm audit --audit-level=high to run
immediately after install rather than last (or not at all, in
publish.yml's case).

Deliberately not doing in this branch: SHA-pinning actions/checkout,
actions/setup-node, and codeql-action, or adding an environment
approval gate. Both are sound hygiene but defend against GitHub/npm
Inc. itself being compromised, lower urgency than the lockfile-bypass
issue above for a single-maintainer repo, and the environment gate
needs an actual GitHub Environment created first.

Verified locally end to end: npm ci --ignore-scripts (194 packages, 0
vulnerabilities), lint, typecheck, coverage (24 tests), build, demo
all pass.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The first version of this branch failed real CI: npm ci --ignore-scripts
on ubuntu-latest left @esbuild/linux-x64 unresolved (vite/vitest/tsx all
depend on esbuild transitively), because --ignore-scripts also disables
esbuild's postinstall fallback that resolves the platform binary when
npm's own optionalDependencies resolution doesn't land it. Local
verification on Windows didn't catch this, esbuild resolved fine there,
which is exactly why the real Linux CI run is the actual check, not a
local pass.

Keeping npm ci (the real fix: pins to the audited lockfile instead of
re-resolving ^ ranges) and npm install -g npm@11.5.1 --ignore-scripts
(installing the npm CLI binary itself has no legitimate need for
scripts and isn't affected by this). Dropping --ignore-scripts only
from the npm ci steps.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@mizcausevic-dev
mizcausevic-dev merged commit f73bb42 into main Sep 13, 2026
4 checks passed
@mizcausevic-dev
mizcausevic-dev deleted the ci/use-npm-ci branch September 13, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant