Skip to content

npm audit threshold diverges across the three repos (high vs moderate), which hid GHSA-253c from two of them #535

Open

Description

@wz-gsa

npm audit runs in all three sibling repos' CI, at two different thresholds:

agentic-coding-patterns    .github/workflows/ci.yml:113               --audit-level=moderate
agentic-coding-quickstart  .github/workflows/markdown-quality.yml:47  --audit-level=high
agentic-coding-playbook    .github/workflows/ci.yml:96                --audit-level=high

All three install the same pinned markdownlint-cli2 from .github/linters/package.json, so they share a dependency tree — but two of them cannot see a moderate advisory in it.

This already happened

GHSA-253c-mchw-3w2r (markdown-it < 14.3.1, MODERATE — linkify: true has two quadratic paths; a few hundred KB of markdown blocks the event loop for tens of seconds) was published 2026-09-29 while all three repos pinned markdown-it 14.2.0 in an overrides block.

It turned patterns CI red. It was completely invisible in quickstart and playbook, which were equally vulnerable.

The sharp part: the overrides block exists for supply-chain hygiene, and in two of the three repos it was holding the vulnerable version open with nothing to say so. The fix landed in quickstart#527 and playbook#297 only because the patterns failure made someone look.

Proposal

Normalize quickstart and playbook to --audit-level=moderate, matching patterns.

Alternative worth considering instead: keep high as the failing gate everywhere and add a non-blocking moderate report, so moderates are visible without becoming a merge blocker. Either is better than two repos being structurally unable to see a class of advisory the third gates on. I have no strong preference and it is a maintainer call — the defect is the divergence, not the specific threshold.

Verified safe to ship now

Earlier this was sequenced behind the markdown-it bump (setting moderate before it would have turned CI red immediately). Both those PRs have merged, so I re-measured from clean scratch clones of each main with a fresh npm ci:

quickstart @ 33c83c5   [email protected] overridden
  audit(moderate) exit=0    audit(high) exit=0    audit(low) exit=0

playbook @ 0c88615     [email protected] overridden
  audit(moderate) exit=0    audit(high) exit=0    audit(low) exit=0

Both are green at every level, so the threshold change ships without a red build.

A note on method, because it bit me: my first attempt measured a stale node_modules in a long-lived clone and reported playbook failing at moderate with [email protected]. That was an artifact of the dirty tree, not the state of main — npm audit reports on what is installed, not what is declared. Every number above is from a fresh clone plus npm ci.

Why file this rather than just do it

The threshold is a policy decision about how much supply-chain risk each repo blocks on, and the three repos disagreeing may be deliberate. But it is currently undocumented either way, and the one time it mattered the divergence hid a real advisory from two of three repos. Happy to open the PRs once the direction is confirmed.


AI-assisted (OpenCode), filed on operator instruction. Advisory; the threshold choice is a maintainer call.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions