Repository navigation
test(supply-chain): pin the .npmrc install-script control to the files it guards - #1325
Merged
Merged
Conversation
…s it guards #1317 landed a root `.npmrc` whose one effective line, `ignore-scripts=true`, is the whole of this repository's defence against dependency lifecycle scripts. Without it `npm ci` runs preinstall/install/postinstall/prepare from every one of ~1490 resolved packages as arbitrary code, before any validator, test or lint step, and four of the eleven install call sites sit in jobs holding a write-scoped GITHUB_TOKEN. Nothing read the control back. `grep -rn "npmrc\|ignore-scripts" tests/ scripts/` returned nothing at 92cede9, so deleting the file, flipping the value, dropping a second .npmrc into a subdirectory, moving an install step off the repository root, or passing --foreground-scripts on an `npm ci` step were all silent, fully green changes. A security control no test reads is a comment. tests/npm-lifecycle-scripts.test.mjs asserts the contract over the real .npmrc, package.json and .github/workflows/** tree: the root .npmrc is the only npm config outside node_modules/, its effective ignore-scripts value is true (last-wins parse, # and ; comments ignored), it still carries the reasoning beside the key, package.json declares no lifecycle hook of its own -- which ignore-scripts would silently skip, a failure that looks like success -- and every workflow install step runs from the repository root without re-enabling the hooks by flag or NPM_CONFIG_IGNORE_SCRIPTS. Each of the six assertions was shown to fail with the control it guards removed, so a green run is evidence the contract was checked rather than evidence there was nothing to look at. Verified at 92cede9 on node v26.10.0: `TZ=UTC node --test` over tests/ reports 2379 pass / 0 fail with this file, 2373 without it, and `npx prettier --check` is clean. No production or workflow file changes. Signed-off-by: quality <quality@hive.kubestellar.io>
Contributor
Author
|
Important Held for human review by the hive's ACMM level gate. This PR was opened by the "quality" agent while Hive policy required a human checkpoint for that agent. Non-outreach agents are held at ACMM L3–L5; the Hive will keep the |
This was referenced Oct 11, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Test Improvement
Adds
tests/npm-lifecycle-scripts.test.mjs. No production, workflow or configuration file changes — one new test file.#1317 landed a root
.npmrcwhose one effective line,ignore-scripts=true, is the whole of this repository's defence against dependency lifecycle scripts. Without itnpm cirunspreinstall/install/postinstall/preparefrom every one of ~1490 resolved packages as arbitrary code on the runner, before any validator, test or lint step, and four of the eleven install call sites sit in jobs holding a write-scopedGITHUB_TOKEN.Nothing read the control back —
grep -rn "npmrc\|ignore-scripts" tests/ scripts/returned nothing at92cede9. This pins the contract over the real.npmrc,package.jsonand.github/workflows/**tree:.npmrcis at the repo root and is the only npm config outsidenode_modules/.npmrcin a subdirectoryignore-scriptsistrue(last-wins parse,#/;comments ignored)package.jsondeclares nopreinstall/install/postinstall/pre*prepare*hookignore-scripts— the failure looks like successnpm ci/npm installstep runs from the repository rootworking-directorythat moves the install out from under the root.npmrc--ignore-scripts=false,--foreground-scripts,NPM_CONFIG_IGNORE_SCRIPTSoverridesWhy these assertions are worth their runtime
Each of the six was shown to fail with the control it guards removed, so a green run here is evidence the contract was checked rather than evidence there was nothing to look at. Mutating
.npmrctoignore-scripts=false, adding apostinstalltopackage.json, and giving aci.ymlinstall stepworking-directory: docsplus--foreground-scriptsturns four of the six red; deleting the comments turns the third red; adding a second.npmrcunderscripts/turns the first red.This is deliberately not filed as a coverage gap:
ignore-scripts=trueis a config key with no executable region, so no coverage profile can ever show it dark. It needs a contract test over the real files, which is what this is.Verification
Branched from
origin/mainat92cede9, node v26.10.0:TZ=UTC node --testovertests/— 2379 pass / 0 fail with this file, 2373 pass / 0 fail without it. The six new tests are the whole of the difference.npx prettier --check tests/npm-lifecycle-scripts.test.mjs— clean.Scope
Disjoint from the other open hold-gated PRs: #1319 (
helpers-script-sandbox,coverage-gate-thresholds,package.json), #1321 and #1323 (bothCONTRIBUTING.mdparity). This adds one new file and touches nothing they touch — in particular it does not editpackage.json, sincenode --testdiscoverstests/without registration.Related Issue
Closes #1324
Human review required.
— hive: agent=quality backend=copilot model=claude-opus-5 copilot=1.0.88