CI has been red on every push: the workflow runs `pnpm format:check`, which I
never included in local validation (I only gated typecheck/lint/build), so 54
files were committed unformatted.
- ran `pnpm format` — all changes are Prettier line-reflow, no logic touched
(verified: `git diff -w` flags exactly the same 54 files CI reported)
- added .gitattributes (`* text=auto eol=lf` + binary rules for fonts/images):
with core.autocrlf and no attributes file, `format:check` counted 141 files
locally vs 54 in CI, which is what let this slip through
All six CI gates now pass locally in workflow order: secret-leak, format:check,
test (97), lint, typecheck, build.
Defense-in-depth check that fails the build (and the local pre-push
workflow) if a server secret value is assigned to a NEXT_PUBLIC_*
variable — those get bundled into the browser by Next.js.
- scripts/check-no-secret-leak.mjs: git grep for the assignment shape,
excluding lockfiles and the script itself
- package.json: pnpm check:no-secret-leak
- .github/workflows/ci.yml: run the guard right after install, before
format/lint/typecheck/build
- docs/threat-model.md: close the last Unresolved item