Appearance
Dependency policy — audits, Dependabot and what "fix" would have cost
Two standards from the operating manual, moved here verbatim on 2026-09-23 (QRS-1288). They are the reason a dependency change in this repo starts with a measurement of reachability, never with the tool's own remediation.
The rule
Never run npm audit fix --force in this repo. Use targeted npm update <pkg> inside existing ranges, then verify by reading the installed framework versions. Triage Dependabot alerts by manifest and reachability, never by severity. Any library, native module, font weight or heavy asset that moves the app-size needle is surfaced with its weight and an alternative before it is installed (see the app-size standard in Engineering standards).
The two standards, as stated
Provenance — moved from CLAUDE.md on 2026-09-23 (QRS-1288)
Verbatim text of CLAUDE.md § "Non-negotiable engineering standards › Security by design" as of commit 00c1eca.
- Security by design — validate at boundaries (Zod), least-privilege, no secret/table leakage, safe errors, RLS on every table, rate limiting on public/auth endpoints, CSP/security headers, dependency/secret/SAST/DAST scanning, PII/GDPR (incl. account/data deletion).
- ⚠⚠ NEVER RUN
npm audit fix --forceIN THIS REPO — IT PROPOSES A CATASTROPHIC DOWNGRADE [measured 2026-08-12, QRS-572]. It wantsexpo→ 53.0.27 andreact-native→ 0.72.17, from 57.0.7 / 0.86.0: back four major SDK versions and fourteen RN minors. That removes New Architecture, Expo Router (the entiresrc/app/routing layer), every version-lockedexpo-*module (secure-store, notifications, image-picker, web-browser), Reanimated's compiled native ABI, and React 19 — both native builds stop compiling andexpo prebuildregenerates different Gradle/CocoaPods projects. All of that to "patch"image-size@1.2.1, which has NO patched version at any release, reachable only through Metro's build-time asset pipeline reading our own committed images on a developer machine. No merchant and no card visitor can reach a bundler, so production exposure is nil. This is "check that the evidence actually supports that specific action" in its most expensive form: the tool's own recommended remediation is the incident. Use targetednpm update <pkg>(moves transitive deps inside existing ranges, nopackage.jsonedit) and then verify by reading installed framework versions, not by trusting the manifest. - Triage Dependabot alerts by MANIFEST, never by severity — it changes every conclusion. Of 43 open alerts on 2026-08-12, ~14 were in
legacy/package-lock.json(not a workspace,paths-ignored inci.yml, never installed, never built, and not even monitored by.github/dependabot.yml, so they can never produce a PR) — including the most alarming-looking row,react-routerhigh/"runtime", which is in the retired Vite SPA and notapps/web. ~9 more were the VitePress docs site. Exactly one of the 43 reached a shipped artifact (nanoid, viaexpo-router's^3.3.8, so it lands in the device bundle). Severity is a property of the advisory; reachability is a property of our tree, and only the second one tells you what to do. ⚠legacy/'s lockfile is kept deliberately — Digital Menu re-homes out oflegacy/in R2.
- ⚠⚠ NEVER RUN