=== M37-S4 dependency vulnerability sweep — evidence ===
Date (UTC)   : 2026-08-08
Branch       : m37-security-perf-ops
Scope        : frontend/ npm dependency tree only. The pure-Python library + CLI and the FastAPI
               backend carry ZERO open Dependabot alerts; every flagged advisory is an npm package
               under the Next.js Web UI. No src/xtalate/ change (30-day nightly-green clock undisturbed).
Tooling      : node v26.5.0 / npm 11.17.0 (local); the compose frontend builds on node:20-alpine.

--- The twelve OPEN alerts GitHub Dependabot flagged, each mapped to the resolved (patched) version ---

  #   sev       package    vulnerable range        resolved after sweep     cleared by
  --  --------  ---------  ----------------------  -----------------------  --------------------------
  #4  critical  vitest     < 3.2.6                 3.2.7                    vitest ^2 -> ^3.2.6 (direct devDep)
  #5  high      vite       <= 6.4.2                6.4.3                    override vite ^6.4.3
  #6  medium    vite       <= 6.4.2                6.4.3                    override vite ^6.4.3
  #2  medium    vite       <= 6.4.1                6.4.3                    override vite ^6.4.3
  #1  medium    esbuild    <= 0.24.2               0.25.12                  override esbuild ^0.25.0
  #8  high      sharp      < 0.35.0                0.35.3                   override sharp ^0.35.0
  #7  high      js-yaml    >= 4.0.0, < 4.3.0       4.3.1                    override js-yaml ^4.3.1
  #18 high      js-yaml    >= 4.0.0, < 4.3.1       4.3.1                    override js-yaml ^4.3.1
  #3  medium    postcss    < 8.5.10                8.5.26                   direct devDep ^8.5.23 + override ^8.5.23
  #9  high      postcss    <= 8.5.11               8.5.26                   direct devDep ^8.5.23 + override ^8.5.23
  #10 high      postcss    <= 8.5.17               8.5.26                   direct devDep ^8.5.23 + override ^8.5.23
  #14 medium    postcss    <= 8.5.22               8.5.26                   direct devDep ^8.5.23 + override ^8.5.23

  => all 12 resolve to a version OUTSIDE the vulnerable range. 12/12 cleared.

--- Why an override for postcss/sharp, not a `next` bump ---

  next@15.5.21 is already the latest 15.x, yet it still bundles postcss 8.4.31 and declares its
  optional image optimizer as sharp ^0.34.3 (resolving 0.34.5). A next bump therefore cannot reach
  the patched versions; an npm `overrides` entry forces next's own copy to the patched (and
  semver-compatible) 8.x / 0.35.x. Our own build's direct postcss devDep was aligned to ^8.5.23 so
  the override does not conflict with a direct dependency (npm EOVERRIDE otherwise).

--- Why vitest 2->3 is a major bump, and why it was necessary ---

  The critical alert (#4, arbitrary file read+exec when the Vitest UI server is listening) has NO
  2.x remedy — 3.2.6 is the first patched release. Xtalate runs `vitest run`, never `vitest --ui`,
  so the live exposure is nil, but the bump is the only way to clear the alert and it clears the
  bundled dev-toolchain vite/esbuild alerts for free. Validated by the full frontend gate + Docker
  e2e below.

  Note: bumping vitest to 3.2.7 alone left vite at 5.4.21 (vitest 3 accepts vite ^5 as a peer, so
  npm kept the existing resolution). Explicit `vite`/`esbuild` overrides were needed to force vite 6
  + esbuild 0.25. All vite consumers in the tree (@vitejs/plugin-react 4.7.0, @vitest/mocker,
  vite-node, vitest) already accept vite ^6, so the override introduced no peer conflict.

--- Relevance judgement ("resolve them if they matter", recorded) ---

  Every one of the twelve is a dev/build-time or unreachable-runtime exposure for THIS app:
    * vite/esbuild (#1/#2/#5/#6): dev-server-only, and Xtalate's Next.js app bundles with
      Turbopack/webpack — vite exists only under the vitest test runner, whose dev server is never
      started by `vitest run`.
    * js-yaml (#7/#18): DoS parsing *untrusted* YAML; here it parses only our own trusted
      docs/openapi.json at build time.
    * postcss (#3/#9/#10/#14): source-map path-traversal / stringifier XSS when processing
      *attacker-controlled* CSS; the build processes our own CSS.
    * sharp (#8): libvips image CVEs reachable through next/image optimizing *untrusted* images;
      the UI serves reports, not user-uploaded images.
  None is a live server-side hole in the deployed service. All were nonetheless resolved: each fix
  is a lockfile-only change with no product-behaviour change, a clean Dependabot slate is itself the
  M37 discipline, and leaving noise lets a real alert hide in it.

--- Also cleared (beyond the 12; housekeeping) ---

  brace-expansion DoS (GitHub alerts #12-#17, which GitHub had AUTO-DISMISSED, so not among the 12
  open): npm audit still flagged the trio locally at high severity. `npm audit fix` (non-force)
  resolved them via safe patch bumps within each major line — 1.1.16 -> 1.1.18, 2.1.2 -> 2.1.4,
  5.0.8 -> 5.0.9 — so `npm audit` reports a fully clean tree.

--- Proof: `npm audit` ---

  found 0 vulnerabilities

--- Proof: resolved versions (`npm ls <pkg> --all`) ---

  vitest@3.2.7
  vite@6.4.3
  esbuild@0.25.12
  js-yaml@4.3.1
  postcss@8.5.26
  sharp@0.35.3
  brace-expansion@1.1.18 / brace-expansion@2.1.4 / brace-expansion@5.0.9

--- Verification (this slice touches frontend/, so both gates were run on-branch) ---

  Frontend gate (under the bumped vitest 3.2.7):
    npm run typecheck  -> tsc --noEmit, clean
    npm run lint       -> next lint, "No ESLint warnings or errors"
    npm run test       -> vitest run, 46 files / 416 tests passed

  Docker e2e (Playwright journeys against the full Tier 1 compose stack, rebuilt with the new
  lockfile; XTALATE_MAX_UPLOAD_BYTES=1048576):
    docker compose up -d --build --wait  -> all services Healthy (frontend serves with new deps)
    npm run e2e                          -> 24 passed
    docker compose down -v               -> stack + volumes removed

--- Post-push note ---

  Dependabot re-scans the dependency graph on push; the twelve alerts auto-close once GitHub sees the
  lockfile no longer resolves any vulnerable version. This artifact is the local proof captured before
  push: the lockfile resolves only patched versions, and `npm audit` is clean.

--- Correction addendum (2026-08-10, v1.0 architectural review F6) ---

The original record's "patched (and semver-compatible) 8.x / 0.35.x" claim is wrong for sharp.
next@15.5.21 declares its optional image optimizer as `sharp: ^0.34.3`, which for a 0.x version
means `>=0.34.3 <0.35.0`; the override forces `sharp ^0.35.0` (lock resolves 0.35.3), which is
OUTSIDE that declared range. The claim is correct for postcss (direct devDep + override aligned
at ^8.5.23, within next's ^8.4.31 caret) — the sharp half of the sentence was the error.

The exposure is dormant, not live: nothing in frontend/app or frontend/components imports
`next/image`, and `npm run build` is clean. The override is deliberately kept — dropping it
reopens the cleared advisory (#8) for nil live exposure, and no patched release exists in the
^0.34.x line to re-pin to.

Standing condition: revisit this override before ever adopting `next/image`. If that feature is
ever introduced, the first task is to re-pin sharp inside next's declared range (or bump next to
a release whose optional range admits the patched sharp), not to ship with the override.
