build: CI builds the bundle and audits what ships; the toolchain advisories are cleared

The server gate adds `vite build` (and with it devOnlyGuard, which until now
first ran inside the image build, after main was pushed) and
`npm audit --omit=dev --audit-level=high`. pip-audit is blocking: when it was
finally read it held three urllib3 advisories with a fix available.
urllib3 goes 2.7.0 -> 2.8.0 as a single in-place pin, passing pip check,
rather than a regeneration that would move every package.

The dev toolchain's 18 advisories are gone:
- vite 5 -> 6.4.3 (path traversal, fs.deny bypass, and esbuild <= 0.24.2
  through it);
- vitest 3 -> 4.1.11 (mocker path traversal);
- typescript-eslint 8.46 -> 8.71;
- `npm audit fix` for the rest.
tsc, eslint, knip, all 2269 tests and the build pass unchanged.

scripts/check-node-modules.mjs checks that frontend/node_modules holds
exactly what package-lock.json pins. The local gate's frontend lanes judge
the host tree, and nothing tied it to the lock the image installs.
This commit is contained in:
2026-10-03 16:50:56 +02:00
parent 7ed2ac4e95
commit b1ff4058ac
5 changed files with 567 additions and 977 deletions
+15 -6
View File
@@ -1,7 +1,9 @@
# Server-side mirror of the local `siftlode check` gate (E1 S3 / DX-1), so `main` is always green
# independent of any one machine. Two jobs match the two local lanes:
# frontend — tsc (3 projects) + eslint + prettier --check + knip + vitest
# backend — ruff + the full pytest suite (pure-logic + the DB-backed lane) against a real Postgres
# frontend — tsc (3 projects) + eslint + prettier --check + knip (both modes) + vitest + vite build
# + npm audit of the production dependencies
# backend — ruff + basedpyright + the full pytest suite (pure-logic + the DB-backed lane) against
# a real Postgres + pip-audit of the lock
#
# They are declared side by side but they DO NOT run in parallel: the lab has a single act_runner
# with one slot, so they queue. Measured across runs #86-#91 — the backend job starts at the exact
@@ -56,6 +58,12 @@ jobs:
- run: npm run format:check
- run: npm run knip
- run: npm run test
# The production bundle (E32): before this, `vite build` — and devOnlyGuard, which fails it if
# dev-only code reaches the bundle — first ran inside the image build, after main was pushed.
- run: npx vite build
# What ships to the browser: a known CVE at high or above in a production dependency fails.
# (The dev tooling's own advisories are burned down by hand; see docs/gates.md.)
- run: npm audit --omit=dev --audit-level=high
backend:
runs-on: ubuntu-latest
@@ -112,8 +120,9 @@ jobs:
- name: pytest
run: python -m pytest
working-directory: backend
# Dependency CVE audit over the pinned lock. Non-blocking for now (informational) — a real CVE
# shows up in the run without failing the gate; tighten to a hard fail once the noise is known.
- name: pip-audit (advisory)
# Dependency CVE audit over the pinned lock. BLOCKING since E32: it ran advisory-only, and when
# it was finally read it had three urllib3 advisories with a fix available (bumped in the same
# change). An advisory without a fix is answered with `--ignore-vuln <id>` here, a reason and a
# date in the comment, and a line in docs/gates.md.
- name: pip-audit
run: pip install --no-cache-dir pip-audit && pip-audit -r backend/requirements.lock
continue-on-error: true