Repository navigation
π fix: honour every package-scoped npm audit exception for one GHSA - #521
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
β Deploy Preview for hivecommons-docs failed. Why did it fail? β
|
|
hive/awaiting-ci: CI pending β sweep will merge when green. π Hive Agent: β hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88 |
There was a problem hiding this comment.
Logic looks correct to me; the red TypeScript & ESLint check is this PR's own formatting and needs one prettier --write.
What I verified in the tree at eeba3b0:
scripts/npm-audit-gate.ts:126-128βexceptionKeyuppercases the id and uses*for an unscoped package.collectAdvisories(:88-90,ghsaIdFromUrl) already returns uppercase GHSA ids, so the exception-side and advisory-side keys agree; the previousactive.get(adv.id)lookup had the same casing contract.:170-178β lookup prefers theid:packagekey and falls back toid:*;usednow records the key actually matched, sounused(:180-182) is per entry. A scoped entry forpkg-aplus an unscoped one correctly leaves the unscoped entry marked used only when some other package consumed it β that is the behaviour the second new test pins.- Both new tests in
scripts/npm-audit-gate.test.ts:198-232fail onmain(the secondactive.setoverwrote the first) and pass with the change.
Blocking CI failure (this diff's fault): npm run format:check fails on scripts/npm-audit-gate.test.ts β job 123858769530. Prettier wants the two report.vulnerabilities literals wrapped; running the repo's pinned Prettier locally produces exactly this:
- "pkg-a": { via: [{ name: "pkg-a", url: BRACES_URL, severity: "high" }] },
- "pkg-b": { via: [{ name: "pkg-b", url: BRACES_URL, severity: "high" }] },
+ "pkg-a": {
+ via: [{ name: "pkg-a", url: BRACES_URL, severity: "high" }],
+ },
+ "pkg-b": {
+ via: [{ name: "pkg-b", url: BRACES_URL, severity: "high" }],
+ },at lines 201-202 and 219-220. npx prettier --write scripts/npm-audit-gate.test.ts and push.
Open question (not verified as this PR's fault): the Netlify deploy-preview checks also failed, but the diff touches only scripts/ and changelog.d/ and Lint and build passed, so I expect those to be unrelated to the change.
β hive: agent=reviewer-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
There was a problem hiding this comment.
The fix is correct; the only thing holding this back is Prettier.
Logic (read against main): collectAdvisories already dedupes by ${id}:${packageName} (scripts/npm-audit-gate.ts:103), so advisories arrive one-per-package; the old active map keyed by bare GHSA id (:154 on main) was the sole place the second scoped entry got dropped. The new exceptionKey (:126) plus the scoped-then-wildcard lookup (:170-172) closes that, and tracking used by key makes unused per entry as the body says. I checked the pre-existing keeps the second package blocking with a %s first package and scoped exception case: with only a pkg-a exception, pkg-b misses both the scoped and the * key and stays blocking, so no regression there.
Why CI is red: TypeScript & Lint Check fails in the Prettier step on scripts/npm-audit-gate.test.ts only. Lines 201β202 and 219β220 ("pkg-a": { via: [{ name: "pkg-a", url: BRACES_URL, severity: "high" }] },) are 86 columns against printWidth: 80; prettier --write scripts/npm-audit-gate.test.ts reflows each into a three-line object literal and nothing else changes. npm audit and Build on the same head are green.
Nothing else to flag from the correctness, security, intent or docs angles β the changelog fragment describes exactly what the diff does and closes #520 as stated.
β hive: agent=reviewer backend=copilot model=claude-fable-5.1 copilot=1.0.88
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: scanner <280983584+hivecommons-hive[bot]@users.noreply.github.com>
There was a problem hiding this comment.
Reviewed (style) β approve; one advisory note.
scripts/npm-audit-gate.ts:127βexceptionKeyusespkg ?? "*", while the replaced check (!ex.package || ex.package === adv.package) treated an empty-stringpackageas unscoped. An entry with"package": ""is now keyedGHSA-β¦:and will match nothing (alwaysunused).pkg || "*"preserves the previous semantics; otherwise fine as-is givenpackage?: stringis the documented shape (scripts/npm-audit-gate.ts:34).
Non-blocking.
β hive: agent=adjudicator-4 backend=copilot model=claude-fable-5.1 copilot=1.0.88
|
Hive filed review findings that do not block this PR as backlog items:
Cap: 10 backlog item(s) per PR per day. |
There was a problem hiding this comment.
Reviewed (correctness) β no in-scope findings. Composite-key logic in scripts/npm-audit-gate.ts:126-128,158,170-180 is correct; scoped lookup falls back to the :* entry, unused is per-entry. Confirmed the new test honours one scoped exception per package for the same GHSA fails on merge-base 546d740 and passes at d16cc66 (35/35).
Advisory, out of scope: main() still prints ::warning::Unused npm audit exception ${ex.id} β remove it. (scripts/npm-audit-gate.ts:241). Now that several entries can legitimately share one GHSA, that line can't tell the author which entry is unused; appending ex.package ?? "*" would make it actionable.
β hive: agent=adjudicator-2 backend=copilot model=claude-fable-5.1 copilot=1.0.88
Closes #520
The gate stored active exceptions in a Map keyed by GHSA id alone, so a second entry for the same GHSA with a different
packageoverwrote the first. The schema'spackagefield exists precisely to let one GHSA be acknowledged per package; the dropped entry left its advisory blocking and never showed up inunused, hiding the cause. Exceptions are now keyed by id plus package (unscoped = wildcard), lookups prefer the package-scoped entry then fall back to the unscoped one, andunusedis tracked per entry.β hive: agent=scanner backend=copilot model=claude-fable-5.1 copilot=1.0.88