$ npm install --no-audit --no-fund
added 99 packages in 967ms
$ npm audit
1124006 [moderate] @hono/node-server
1130720 [high] fast-uri
1130722 [high] ip-address
1130723 [moderate] ip-address
1130724 [moderate] ip-address
1130733 [moderate] hono <-- all six still here
resolved tree:
@modelcontextprotocol/sdk@1.30.0 <-- SDK DID move (was 1.29.0)
@hono/node-server@1.19.14 <-- but this stayed
hono@4.12.31 <-- and this
ajv@8.20.0 -> fast-uri@3.1.4 <-- and this
express-rate-limit@8.5.1 -> ip-address@10.2.0
npm install only adds and removes. Any transitive that still satisfies its
declared range is left exactly where it is. The SDK itself upgraded 1.29.0 to 1.30.0 because
the manifest demanded ^1.30.0 and the lockfile was stale, but every dependency
underneath it already satisfied its own range, so npm had no reason to touch them.
$ npm update --no-audit --no-fund
changed 14 packages in 3s (src/mcp-server)
changed 23 packages in 8s (src/hooks)
$ npm audit
(no findings)
resolved tree:
@modelcontextprotocol/sdk@1.30.0
@hono/node-server@2.1.0 <-- range was ^1.19.9 || ^2.0.5
hono@4.13.0 <-- range was ^4.11.4
ajv@8.20.0 -> fast-uri@3.1.5 <-- range was ^3.0.1
express-rate-limit@8.6.1 -> ip-address@10.4.0
$ bash tests/security/test-npm-audit.sh
Total: 4 | Passed: 4 | Failed: 0
npm update walks each declared range to its newest satisfying version.
Every fix already lived inside a range the manifests permitted, so nothing semver-major
was involved and no manifest was edited. The fixes had been sitting there, unreachable
only because the lockfile pinned older members of the same ranges.
| ID | Sev | Package | before | after | Status |
|---|---|---|---|---|---|
| 1130733 | moderate | hono | 4.12.31 | 4.13.0 | cleared |
| 1130720 | high | fast-uri | 3.1.4 | 3.1.5 | cleared |
| 1130722 | high | ip-address | 10.2.0 | 10.4.0 | cleared |
| 1130723 | moderate | ip-address | 10.2.0 | 10.4.0 | cleared |
| 1130724 | moderate | ip-address | 10.2.0 | 10.4.0 | cleared |
| 1124006 | moderate | @hono/node-server | 1.19.14 | 2.1.0 | cleared |
| 1130709 | moderate | postcss | 8.5.18 | 8.5.25 | cleared |
| Check | Result |
|---|---|
| tests/security/test-npm-audit.sh | 4/4 workspaces, 0 findings, exit 0 |
| src/hooks build | clean, 11 bundles, 670 KB |
| src/hooks vitest | 304 files, 7501 passed, 2 skipped |
| files changed | 2 lockfiles only, no manifest edits |
Its recorded reason says "no upstream fix yet", which stopped being true the moment
@hono/node-server resolved to 2.1.0. Removing it is correct but is a separate
concern from the lockfile, and the entry is harmless while it sits unused
(it expires 2026-09-01 on its own).
Six of the nine open code-scanning alerts point at three unpinned FROM
node:24-alpine lines, counted twice because plugins/ is generated from
src/. The file already carries a written rationale for tag-pinning over digest-pinning:
a digest freezes the base layer so it can never pick up an upstream security patch. Silently
"fixing" that would overturn a documented decision in a skill template. It needs a decision,
not a patch.
The PR Playground gate exempts bot branches and an inert path list
(README, CHANGELOG, .github/, vercel.json, *.toml). package-lock.json
is not on it, so this PR (two lockfiles, zero user-facing surface) had to author one.
That is the same shape as the failure the gate's own comment describes for #3193.
Worth a follow-up, not worth gaming the branch prefix to dodge.