Skip to content

fix(deps): take the fixes for proxy-addr, source-map-js and katex that turn main's OSV scan red - #21951

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-21945-osv-lockfile-fixes
Oct 6, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-21945-osv-lockfile-fixes

Conversation

@objectstack-fleet

Copy link
Copy Markdown
Contributor

Part of #21945

Clause-②: no

What this does

Validate Package Dependencies runs OSV-Scanner against pnpm-lock.yaml. On main it reports four advisories, so the scheduled scan is red, and so is every PR that touches a package.json. Three of the four name a fixed version, and this PR takes those three fixes. The fourth, sprintf-js, has no fixed release. Its [[IgnoredVulns]] entry is on branch claude/issue-21945-osv-exemption, in its own osv-exemption PR, as convention 3 in osv-scanner.toml's header requires.

Which half this leaves: GHSA-hp3w-g68c-fv3c (sprintf-js). This PR alone does not turn the OSV step green, and neither does the exemption PR alone. The card stays open when this PR merges, and the PM finishes it after both have landed.

OSV reading: before and after

Measured locally with OSV-Scanner v2.3.8, the version validate-deps.yml pins. api.osv.dev answers 403 from this container, so the scan ran in offline mode (--offline-vulnerabilities --download-offline-databases) against the OSV npm database the scanner downloaded on 2026-10-06.

main at d16b9fbf (exit 1). These are the same four rows the scheduled run 37407261685 reported:

| https://osv.dev/GHSA-238p-pmpm-9mq7 | 2.1  | npm       | katex         | 0.16.47 | 0.18.2        | pnpm-lock.yaml |
| https://osv.dev/GHSA-jqcg-44mw-7w3h | 9.1  | npm       | proxy-addr    | 2.0.7   | 2.0.8         | pnpm-lock.yaml |
| https://osv.dev/GHSA-68fv-2mgg-jv7q | 8.7  | npm       | source-map-js | 1.2.1   | 1.2.2         | pnpm-lock.yaml |
| https://osv.dev/GHSA-hp3w-g68c-fv3c | 6.9  | npm       | sprintf-js    | 1.1.3   | --            | pnpm-lock.yaml |

This PR at e142f120 (exit 1, one row left, which the exemption PR covers):

| https://osv.dev/GHSA-hp3w-g68c-fv3c | 6.9  | npm       | sprintf-js | 1.1.3   | --            | pnpm-lock.yaml |

This PR's lockfile scanned with the exemption PR's osv-scanner.toml: exit 0, No issues found, with one vulnerability filtered.

Changes

pnpm-lock.yaml: proxy-addr 2.0.8 and source-map-js 1.2.2

Every parent's declared range already admits the fix: express 5.2.1 declares proxy-addr ^2.0.7, and postcss 8.5.28, @tailwindcss/node 4.3.3, css-tree 3.2.1 and magicast 0.5.3 declare source-map-js ^1.2.1. So this is a re-lock and needs no new pin.

  • Rejected: pnpm update proxy-addr source-map-js -r --depth Infinity. It re-resolved unrelated packages: @inquirer/*, @napi-rs/wasm-runtime, node-abi, a second postcss, nanoid and ip-address copy, and knex's peer set. That was +81/−60 lines.
  • Taken: a temporary override pair (proxy-addr to 2.0.8, source-map-js to 1.2.2), installed and then removed, followed by a second install. The lockfile keeps the two resolutions and nothing else moves: +11/−11 lines, the two package entries and the five dependent edges. pnpm-workspace.yaml ends that step byte-identical to main.

pnpm-workspace.yaml overrides: plus pnpm-lock.yaml: katex to ^0.18.2

  • Where: in pnpm-workspace.yaml. The root package.json has no pnpm.overrides (its pnpm field holds only ignoredBuiltDependencies), and the block's own header records that pnpm v10 reads overrides from this file.
  • Selector shape: 'katex@>=0.11.0 <0.19.0': '^0.18.2'. The floor is the advisory's introduced (0.11.0), and the bound sits at the caret boundary of the 0.18 target line. That is the durable shape the block header and check:override-consistency describe: the bound sits above the target's line, so a later lift moves only the target.
  • Resolution: ^0.18.2 resolves to 0.18.10, not 0.18.11, because npm deprecates 0.18.11 ("Accidentally published with breaking changes. Use 0.19.0 instead."). katex 0.18's CLI dependency moves commander 8.3.0 to 15.0.0, which was already in the tree, so commander@8.3.0 drops out. Lockfile +6/−11.
  • Why an override, and not a dedupe: no published mermaid admits the fix. Measured with npm view mermaid@V dependencies.katex: 11.16.0 and 11.16.1 declare ^0.16.45, and 11.17.0, 11.17.1, 11.17.2, 12.0.0 and 12.1.0 (latest) declare ^0.16.47. This override forces mermaid past its own declared range, so it needs evidence that mermaid still works.
  • Note: the entry carries a note in the block's style. It states the advisory, the forced-upgrade caveat and the evidence below.

Totals: pnpm-lock.yaml +17/−22; pnpm-workspace.yaml +33/−0 (one entry plus its note).

Evidence that katex 0.18 works for the only consumer

The only path to katex is apps/docs, then mermaid ^11.16.0 (11.16.1), then katex. Nothing else in the workspace names katex (git grep -i katex, lockfile excluded: zero hits).

  1. Where mermaid touches katex. It does so in one place, renderKatexUnsanitized in dist/chunks/mermaid.core/chunk-I66GZJ75.mjs. That is a lazy import("katex") followed by katex.renderToString(c, { throwOnError: true, displayMode: true, output }), where output is "mathml" or "htmlAndMathml". The katex 0.17 and 0.18 breaking changes (the internal __defineFunction API, and the prefixed internal CSS classes) touch neither that call nor the outer .katex class mermaid styles (.node .katex path). The 0.19.0 strict-mode change is outside the target line.
  2. Node. Through mermaid's own resolution, katex.version is 0.18.10, and renderToString with mermaid's options returns MathML for both output modes.
  3. Browser. A bundle of the real mermaid@11.16.1 mermaid.core.mjs ran in headless Chromium with the same initialize() options apps/docs/components/mermaid.tsx passes (securityLevel: 'strict'). It rendered a flowchart whose label is $$x^2 + \frac{a}{b}$$ with this result: {"katexVersion":"0.18.10","hasMath":true,"hasMsup":true,"hasFrac":true,"unsupported":false,"errored":false,"pageErrors":[]}.
  4. Docs build, local. next build in apps/docs ran under the shared verify lock (VERDICT command-exit 0; compiled in 119s; 1240/1240 static pages; BUILD_ID written). The client chunk carries katex version:"0.18.10", and no 0.16.47 remains in .next/static/chunks. This was next build alone, not the full vercel.json command: the docs app reads only packages/spec/package.json from the spec, and the committed content/docs/references stood in for gen:schema/gen:docs. The PR's Build Docs job runs the production command.
  5. Advisory direction. Under a polluted Object.prototype.trust, \href{…}{x} through katex 0.16.47 emits a link, and through 0.18.10 it does not.

No page in content/ puts $$ inside a mermaid block today, so this path is latent rather than live. The proof is still of the code that would run.

Changeset

skip-changeset. The diff touches pnpm-lock.yaml and pnpm-workspace.yaml, both repo-root configuration. Neither is in any package's files[], and overrides do not reach downstream installs, so nothing publishes.

Local verification, at e142f120

  • pnpm install --frozen-lockfile --prefer-offline: exit 0.
  • The gates come from node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack at this head: 22 commands, the same list the dispatch named. The --ran reconciliation is filled in below.
  • check:override-consistency: green. katex appears in neither census: mermaid consumes it, and the bound clears the target floor.

--ran reconciliation, with exit codes recorded before any pipe: 22 derived, 18 run, 4 NOT-MEASURED, 0 UNRUN.

Gate Exit
node scripts/check-changeset-fixed.mjs 0
node scripts/check-closing-keyword-parity.mjs (+ --self-test) 0 / 0
node scripts/check-comment-mask-corpus.mjs 0
node scripts/check-dts-emitted.mjs --self-test 0
node scripts/check-osv-exemptions.mjs (+ --self-test) 0 / 0
node scripts/check-prerelease-pin-watch.mjs --self-test ; --verbose 0 / 0
pnpm --filter @objectstack/spec run check:llms-txt 0
pnpm check:driver-memory-census · check:gitlink-declared · check:nul-bytes · check:override-consistency · check:refd-timer-probe · check:vendor-export-contract-resolve · check:watch-hint-literal · check:workspace-manifest-cycles 0 each
pnpm check:dts-closure · check:dual-build-cjs-loads · check:lean-entry-closure · check:sourcemap-no-sources-content 3, PREREQUISITE NOT MET

NOT MEASURED (four gates). They read every package's built dist/. This diff touches no package source, so the local scope builds no package, and the build these four need is the full pnpm build. CI's Build Core and Lint & Repo Gates measure them on the built tree. Both NOT MEASURED readings are declared here and are not counted as passes.

Not run locally, CI's: the path-scheduled jobs dispatch-gates lists (Test Core, Temporal Conformance, Dogfood Regression Gate, Dogfood Verify CLI, Build Core, Build Docs) and the type-check lanes.

Acceptance notes

  • pnpm install prints ioredis-mock 8.13.1: unmet peer ioredis@^5: found 6.0.0. That warning is already present on main: the lockfile there resolves the same pair, and packages/services/service-cluster-redis/src/ioredis-pair.pin.test.ts pins it. It is not from this diff.

Generated by Claude Code

claude added 3 commits October 6, 2026 04:41
…jqcg-44mw-7w3h and GHSA-68fv-2mgg-jv7q

Both fixed versions are admitted by every parent's declared range
(express ^2.0.7; postcss, @tailwindcss/node, css-tree, magicast ^1.2.1),
so the lockfile only had to move off the two vulnerable resolutions.
Done through a temporary override pair, installed and then removed, so
no other resolution moved (11 insertions, 11 deletions); a plain
`pnpm update -r --depth Infinity` re-resolved eleven unrelated
packages and was rejected.

Claude-Session: https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw
Co-authored-by: Claude <noreply@anthropic.com>
No published mermaid admits the fixed line (11.16.1 declares
^0.16.45; 11.17.0 through 12.1.0 declare ^0.16.47), so this is an
override past the dependent's declared range, not a dedupe. The
selector follows the overrides block's header rule: floor at the
advisory's 0.11.0, bound at the 0.19.0 caret boundary of the target
line. The target resolves to 0.18.10 because npm deprecates 0.18.11.
mermaid's only katex call (renderToString with throwOnError,
displayMode and output) renders MathML through 0.18.10 in Chromium.

Claude-Session: https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw
Co-authored-by: Claude <noreply@anthropic.com>
…ut the katex entry

The note claimed the gate lists katex as an override it cannot
cross-check. Measured on this tree, it says nothing about the entry:
nothing publishable declares katex, mermaid consumes it, and the
selector's bound clears the target floor, so neither census reports it.

Claude-Session: https://claude.ai/code/session_01VF48aw8RPG6wzDnMgp6rtw
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/s dependencies Pull requests that update a dependency file labels Oct 6, 2026
@objectstack-fleet objectstack-fleet Bot added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Oct 6, 2026
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

Correction to this PR's body, from the domain:devx seat 2 reviewer (session_01VF48aw8RPG6wzDnMgp6rtw), 2026-10-06T05:12Z. The dev's PR bodies are write-once, so the correction is recorded here.

The body says the local scan used "OSV-Scanner v2.3.8, the version validate-deps.yml pins". That is not what CI runs. validate-deps.yml:142 pins the action by sha with the comment # v2.3.8, but the job pulls the image ghcr.io/google/osv-scanner-action:v2.5.0. Scheduled run 37407261685, job 112087469784, step "Run google/osv-scanner-action/…" shows that pull.

Corrected reading: the local scans were measured with OSV-Scanner v2.3.8 and v2.5.0 (the image the CI job pulls). Both give identical rows on every tree. The verdicts in the body are unchanged.


Generated by Claude Code

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

Labels

dependencies Pull requests that update a dependency file size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants