{ "$comment": "Single source of truth for static deny-lists exercised by scripts/run-tests.sh static profile. Adding/removing entries here is the gate code-review enforces (per AZ-482 constraint: 'deny-list lives in tests/security/banned-deps.json so additions are visible in code review'). Each section names the AC it traces to and is consumed by scripts/check-banned-deps.mjs.", "ml_libs": { "ac": "NFT-SEC-10", "scope": "package.json (dependencies + devDependencies)", "match": "regex-on-name", "patterns": [ "onnxruntime", "tensorflow", "tflite", "coreml", "tfjs", "@tensorflow/", "@huggingface/", "transformers\\.js" ] }, "signature_libs": { "ac": "NFT-SEC-11", "scope": "package.json (dependencies + devDependencies)", "match": "regex-on-name", "patterns": [ "jsrsasign", "tweetnacl", "@noble/", "^jose$", "^jsonwebtoken$", "^node-forge$" ] }, "persistence_libs": { "ac": "O2 (NFR) — no client-side persistence library", "scope": "package.json (dependencies + devDependencies)", "match": "regex-on-name", "patterns": [ "^localforage$", "^idb$", "^dexie$" ] }, "ws_graphql_ssr_libs": { "ac": "O11 (NFR) — no SSR/WS/GraphQL", "scope": "package.json (dependencies + devDependencies)", "match": "regex-on-name", "patterns": [ "^ws$", "^socket\\.io$", "^graphql$", "^apollo$", "@apollo/", "^grpc-web$", "^react-dom/server$" ] }, "legacy_integrations": { "ac": "NFT-SEC-13 — dropped legacy integrations not present in source", "scope": "src/ and mission-planner/ (production sources; tests excluded)", "match": "ripgrep-pattern", "patterns": [ "WhatsApp", "TelegramBot", "D-Bus", "libsignal" ] }, "concurrent_edit_patterns": { "ac": "NFT-SEC-14 (AC-N1 anti-criterion) — no concurrent-edit reconciliation surface", "scope": "src/ and mission-planner/ (production sources; tests excluded)", "match": "ripgrep-pattern", "patterns": [ "concurrent.edit", "operational.transform", "crdt", "y-?websocket" ] }, "owm_key_in_dist": { "ac": "NFT-SEC-09 (AC-1, dist/ portion) — OpenWeatherMap key not shipped in built bundle", "scope": "dist/ (post-`bun run build` artifacts)", "match": "literal", "patterns": [ "335799082893fad97fa36118b131f919" ] }, "owm_key_in_source": { "ac": "NFT-SEC-09 (AC-1, source portion) — OpenWeatherMap key not present in source tree", "scope": "src/ and mission-planner/ (production sources; tests excluded)", "match": "literal", "patterns": [ "335799082893fad97fa36118b131f919" ] }, "alert_calls": { "ac": "NFT-SEC-07 (AZ-466 AC-5) — no alert() in production source", "scope": "src/ and mission-planner/ (production sources; tests excluded)", "match": "ripgrep-pattern", "patterns": [ "\\balert\\s*\\(" ], "$allowlist_comment": "Snapshot of currently-allowed alert() locations. Phase B feature tasks should drain this list one entry at a time. New alerts are blocked by the static check; removing an entry is a code-review-visible improvement.", "allowlist": [ "src/features/annotations/MediaList.tsx", "src/features/flights/FlightsPage.tsx", "mission-planner/src/flightPlanning/JsonEditorDialog.tsx", "mission-planner/src/flightPlanning/flightPlan.tsx" ] }, "destructive_surfaces": { "ac": "NFT-SEC-08 (AZ-466 AC-4) — every destructive surface is reviewed and either gated by ConfirmDialog or recorded as a known drift", "scope": "src/ files that call api.delete( or destructive api.patch(", "match": "file-level: a file containing a destructive call MUST be listed below; new destructive surfaces FAIL the check", "patterns": [ "api\\.delete\\(", "api\\.patch\\([^,]+,\\s*\\{\\s*isActive\\s*:" ], "$gated_comment": "Files that perform destructive mutations AND wire ConfirmDialog around them. Code review checks the wiring per file.", "gated": [ "src/features/annotations/MediaList.tsx", "src/features/flights/FlightsPage.tsx" ], "$drift_comment": "Files that perform destructive mutations WITHOUT a ConfirmDialog gate today. Phase B follow-up tasks land the gate and move each entry to `gated`. Adding a new entry here requires a code-review reason.", "drift": [ "src/features/admin/AdminPage.tsx" ] } }