Skip to content

build(node): pin npm integrity and Node 22/jsdom 30 compatibility - #896

Draft
seonghobae wants to merge 168 commits into
developfrom
fix/node-22-22-2-jsdom-30-779
Draft

seonghobae wants to merge 168 commits into
developfrom
fix/node-22-22-2-jsdom-30-779

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 17, 2026

Copy link
Copy Markdown
Collaborator

Canonical Node / npm runtime owner

This Draft owns the Node 22 / jsdom 30 compatibility vertical and the repository-wide npm runtime acquisition/provenance contract. #1176 remains the canonical writer for the inherited Ruff formatting prerequisite; #896 consumes that delta by ancestry rather than reimplementing it.

Exact current identity

Runtime / supply-chain contract

  • Node runtime remains >=22.22.2 <23, with an exact-minimum Node 22.22.2 CI lane.
  • npm remains exactly 10.9.9; executing npm is verified together with bundled tar >=7.5.19 before dependency extraction.
  • Root packageManager is integrity-bound to the reviewed npm 10.9.9 SHA-512 artifact.
  • scripts/checks/activate_pinned_npm_runtime.sh is the single workflow-level activation path for direct npm execution.
  • Only Corepack acquisition may retry, only on admitted ETIMEDOUT, at most three attempts with 5 s / 10 s backoff.
  • Signature, integrity, key-id, metadata, checksum/hash mismatch, unknown Corepack failures and mixed trust+timeout diagnostics fail closed before npm enable/audit/dependency admission.
  • There is no fallback to Node-bundled/system/latest npm or retry around npm ci, tests, build/package/release actions.

Current hosted RED → repair

Exact predecessor 6763d9158cf93798f62d8e42c20ac400b7ca0a1d produced a real hosted CI failure after the runtime path itself succeeded.

On gate / ci / node-minimum-compatibility (macOS), Node 22.22.2 setup, integrity-bound npm 10.9.9 acquisition, bundled tar verification, frozen Node dependencies, Python sync, stable Rust/numeric extension, lint and typecheck all completed. The Python suite then exposed that the helper used Bash 4-only ${acquisition_output,,} under hosted macOS /bin/bash, causing bad substitution before trust-first/timeout classification could run. The same exact head on Linux did not have that shell failure and instead exposed two stale source-contract assertions: the Node/jsdom test still expected bare npm@10.9.9, and the resilience structural test still searched source for uppercase "ETIMEDOUT" after the classifier had intentionally moved to lowercase matching.

Causal repairs on the same owner lane:

  • 2a080035cb66ea1a5a4e1cf9b3682c1a23e35b29: replace ${acquisition_output,,} with portable LC_ALL=C tr '[:upper:]' '[:lower:]'; trust markers still take precedence over etimedout.
  • e3ecc44a873a44588855312ddcf4f96436d0f86b: remove the contradictory bare-version package-manager assertion from the Node/jsdom test. Full version+SHA-512 identity remains owned by test_npm_package_manager_integrity_pin.py.
  • 4974765fd8145eb605637e8a84cf955441b8b3d7: structural regression now requires portable normalization, lowercase matcher source, and absence of Bash-specific ${acquisition_output,,} while behavioral fixtures continue to emit uppercase ETIMEDOUT.
  • c37835f150a01b8fc5745b541e51ef79bce830af: code-current TRACEABILITY for the hosted portability RCA and claim boundary.

The failed 6763d915... run is predecessor RED evidence only. It proves the exact runtime acquisition path reached npm 10.9.9 successfully on macOS/Linux, but its failing verdict does not transfer to the moved current head.

Earlier fail-closed repairs retained

  • RED bc26032... → repair 4cee8f5d...: provenance/integrity failure takes precedence over an ETIMEDOUT token in the same Corepack diagnostic.
  • 628aa96b...2ddd8b15... / ab04754d...: remove weaker workflow-local Corepack activation from release/security paths.
  • df20e638...: discover direct npm execution across repository workflows rather than one install-command spelling.
  • a990e7c7...: remove the legacy inline-activation fallback from test_npm_toolchain_contract.py.
  • RED 19ddd51d... → repair dc726efb...: detect npm behind ordinary shell control syntax (then, do, grouping, negation, exec) without treating harmless echo npm ... text as a consumer.
  • RED 237ff476... → repair eee83e3a...: normalize shell escaped-newline token joining before direct-npm admission.

Current exact-head evidence

Fresh repository generations now exist for c37835f150a01b8fc5745b541e51ef79bce830af:

  • SAST Semgrep 35660841954: queued;
  • build-baseline 35660842172: queued;
  • Security Scan 35660842433: queued;
  • sbom 35660842213: queued;
  • CodeQL PR 35660842048: pending;
  • ci 35660842046: queued.

Queued/pending is non-passing. The predecessor RED and predecessor native successes do not transfer.

Formal review inventory still contains only two historical GitHub Advanced Security COMMENTED submissions. Their Scorecard threads refer to the removed standalone workflow and are resolved/outdated. There is no qualifying independent non-author current-head APPROVED. Keep Draft.

Downstream consumer / owner boundary

Score Storage #1241 is downstream evidence, not an npm-runtime source owner. Required order remains:

#896 protected integration → ordinary/non-force #1241 reconciliation → consume the protected helper in score-storage-native.yml → fresh exact-head UI execution.

#1241 must not vendor this mutable Draft helper. Production separation/model behavior remains Signal/MIR ownership; #896 does not mock/narrow that product path or copy MIR source.

Merge gate

One unchanged final head must obtain terminal-success applicable repository/central CI, native builds, security/SAST/SBOM/supply-chain/CodeQL gates, zero valid unresolved findings, and a qualifying independent non-author current-head approval before ordinary merge.

No self-approval, force-push, destructive rebase, gate weakening, source-neutral freshness commit, blind rerun, bundled/system/latest npm fallback, integrity bypass, predecessor-evidence transfer, filename exception for a new npm consumer, inline activation bypass, shell-control-flow or escaped-newline bypass, timeout-over-provenance precedence, or source-copy repair into downstream consumers.

seonghobae and others added 30 commits August 7, 2026 16:26

Copy link
Copy Markdown
Collaborator Author

Exact-current hosted evidence update for 347530bd4989aa20bdfca320ea5b1dd2e722ccad after the SHA-512 package-manager pin:

  • build-baseline run 35576316674 is executing on this exact head.
  • macOS arm64 job 106258896942 is terminal SUCCESS. Its Activate and verify pinned npm runtime, frozen dependency install, Python sync, frontend/native build, package and upload steps all succeeded.
  • Windows amd64 job 106258896443 has already passed integrity-bound npm activation, dependency install, Python sync and frontend build; native build is still in progress.
  • macOS amd64 job 106258896787 has passed integrity-bound npm activation, dependency install, Python sync and frontend build; native build is still in progress.
  • Windows arm64 job 106258896784 has passed integrity-bound npm activation; dependency installation is still in progress.
  • ci, CodeQL PR, Semgrep, Security Scan and SBOM remain queued/pending at the latest fresh reads.

This is real current-head evidence that Corepack accepts the reviewed npm@10.9.9+sha512... locator on hosted Windows/macOS runners; it is not an overall GREEN verdict. Keep Draft, do not transfer predecessor evidence, and do not rerun/no-op wake while the current generation is active.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: ci-cd CI, GitHub Actions, checks, release, or supply chain maintenance priority: medium Normal-priority or P2 work status: draft Draft pull request type: maintenance Maintenance, build, dependency, or operational upkeep

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants