Skip to content

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 --force IN THIS REPO — IT PROPOSES A CATASTROPHIC DOWNGRADE [measured 2026-08-12, QRS-572]. It wants expo → 53.0.27 and react-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 entire src/app/ routing layer), every version-locked expo-* module (secure-store, notifications, image-picker, web-browser), Reanimated's compiled native ABI, and React 19 — both native builds stop compiling and expo prebuild regenerates 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 targeted npm update <pkg> (moves transitive deps inside existing ranges, no package.json edit) 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 in ci.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-router high/"runtime", which is in the retired Vite SPA and not apps/web. ~9 more were the VitePress docs site. Exactly one of the 43 reached a shipped artifact (nanoid, via expo-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 of legacy/ in R2.