Skip to content

Operational Status & Gates

Two operational facts cut across every chapter and every pull request. So they don’t drift out of sync, they live here once — the other chapters link back rather than restating them.

.github/workflows/ci.yml runs on every push to main and every pull request. It is the merge gate. Cloudflare Workers Builds deploys the worker independently on each push to main.

The jobs:

Job What it gates
typecheck / unit tests pnpm --filter @brightblur/web check then test:unit. Lint, Knip and pnpm audit also run here but non-blocking (continue-on-error) — they surface backlogs (bri-284a lint, bri-edf9 dead code, bri-60d5 advisories) without gating merges.
mobile typecheck tsc --noEmit across apps/mobile — the native app can no longer merge ungated.
build The Cloudflare adapter build, model-checksum verification, and the scheduled-handler injection (bri-20cf) — all of which previously only failed at deploy time.
apply D1 migrations (production) On push to main only, after verify + build are green: applies any pending migrations to production D1 (db:migrate:remote). Idempotent — prints “No migrations to apply!” and exits 0 when there’s nothing pending.

The 2026-07-13 dependency refresh reduced pnpm audit --prod from 18 findings (8 high, 6 moderate, 4 low) to three findings (0 high, 2 moderate, 1 low). The remaining packages cannot be upgraded through their parents’ supported version ranges. They are retained without pnpm overrides for the following concrete reasons:

Advisory Dependency path Reachability and disposition
GHSA-pxg6-pf52-xh8x (cookie 0.6.0, low) bits-ui → runed → @sveltejs/kit → cookie The flaw requires an attacker-controlled cookie name, path, or domain. Every BrightBlur cookies.set/cookies.delete call uses a source constant or literal for those fields; request data is used only as a cookie value. SvelteKit 2.69.2 still declares cookie@^0.6.0, so forcing 0.7 would cross its declared 0.x range. Track the SvelteKit parent instead.
GHSA-qx2v-qp2m-jg93 (postcss 8.4.49, moderate) expo → @expo/metro-config → postcss This is native-app build tooling, not shipped runtime code. Exploitation requires attacker-controlled CSS to be stringified into an HTML <style> context; the mobile workspace has no CSS/PostCSS configuration or user-CSS input. Expo SDK 54 pins postcss@~8.4.32, so 8.5.10 is outside its supported range. Upgrade with a future Expo SDK rather than overriding Metro’s pin.
GHSA-w5hq-g745-h8pq (uuid 7.0.3, moderate) expo → @expo/config-plugins → xcode → uuid This is iOS project-generation tooling, not shipped runtime code. The advisory affects the v3, v5, and v6 output-buffer APIs; xcode@3.0.1 calls only uuid.v4() and supplies no external output buffer. Its declared range is uuid@^7.0.3; forcing the patched 11.x major would be unsupported. Track the Expo/xcode parent instead.

Re-run pnpm audit --prod on dependency changes. Any new finding, any high or critical finding, or a changed path/usage that invalidates the reachability analysis above must be investigated rather than accepted under this note.

The migrate-prod job and Workers Builds start on the same push, in parallel. So a merge deploys code and applies schema roughly together, not in a guaranteed order:

  • Additive migrations (CREATE TABLE, ADD COLUMN … NULL) are safe — new code may briefly see a missing table, then succeeds once migrations finish moments later.

  • Destructive or required-NOT NULL changes are not safe to race. Apply them manually before merging:

    Terminal window
    cd apps/web && pnpm db:migrate:remote
    wrangler d1 migrations list brightblur --remote --env production # verify

Prefer additive migrations that an already-deployed older schema can tolerate — deploys are code-then-schema, the reverse of the safe expand/contract order.

Permanent. This gate lives outside CI: the heavy upload e2e isn’t in the pipeline yet, so it’s on you to run it when the runtime changes.

Any change to apps/web/src/lib/image/tflite-runtime.ts or the worker bootstrap must be validated with the heavy upload e2e against a production build:

Terminal window
cd apps/web && pnpm build && npx playwright test upload.test.ts --project=chromium-heavy

pnpm check and pnpm test:unit cannot catch a regression here: the importScripts polyfill branch is unreachable from Vitest by design (an XMLHttpRequest guard keeps it off Node). This is how the June 2026 _malloc incident reached production. Recognition explains what the polyfill does; Conventions has the e2e harness prerequisites — the .dev.vars flags, port 4173, and the local db:migrate.