{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-4aec4d46c0fc2658", "name": "TODO/FIXME marker in shipping code \u2014 claude-design-reference/onboarding/02-base-components.js:46", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 claude-design-reference/onboarding/02-base-components.js:46"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-33b364cce42d601f", "name": "Stray `console.log` in TS/JS \u2014 claude-design-reference/onboarding/07-onboarding-flow.jsx:86", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 claude-design-reference/onboarding/07-onboarding-flow.jsx:86"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7635b75e8e7fecbc", "name": "TODO/FIXME marker in shipping code \u2014 mobile/src/screens/ProgressScreen.tsx:307", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 mobile/src/screens/ProgressScreen.tsx:307"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3738c04c7ce03edc", "name": "Stray `console.log` in TS/JS \u2014 mobile/src/utils/notifications.ts:143", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 mobile/src/utils/notifications.ts:143"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-183753034450eecd", "name": "Stray `console.log` in TS/JS \u2014 backend/src/db.js:51", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/db.js:51"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b74a55f96eb9e099", "name": "Stray `console.log` in TS/JS \u2014 backend/src/index.js:75", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/index.js:75"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-afaac8bd118d4b2e", "name": "Stray `console.log` in TS/JS \u2014 backend/src/routes/analyzeFood.js:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/routes/analyzeFood.js:28"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e489c2596eb5ef22", "name": "Stray `console.log` in TS/JS \u2014 backend/src/routes/extractRecipe.js:59", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/routes/extractRecipe.js:59"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9c6f5650cf749413", "name": "Very large file: scripts/extract-pdf/taco.ts (5927 lines)", "shortDescription": {"text": "Very large file: scripts/extract-pdf/taco.ts (5927 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-47187f75df4405b7", "name": "Very large file: mobile/src/state/AppContext.tsx (1576 lines)", "shortDescription": {"text": "Very large file: mobile/src/state/AppContext.tsx (1576 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-221dcb46c8d224c4", "name": "Very large file: mobile/src/screens/RecipesScreen.tsx (1850 lines)", "shortDescription": {"text": "Very large file: mobile/src/screens/RecipesScreen.tsx (1850 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-50b955d54ed75bb5", "name": "Very large file: mobile/src/screens/ProgressScreen.tsx (1822 lines)", "shortDescription": {"text": "Very large file: mobile/src/screens/ProgressScreen.tsx (1822 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "1 test file(s) for 159 source file(s) (ratio 0.01). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 132 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 60 placeholder/mock markers across 36 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: ci, tests, operator-readme. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing ci, tests, operator-readme. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-dae9813dfce98376", "name": "Commented-code block (6 lines) in scripts/extract-pdf/parse-recipes.mjs:24", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/extract-pdf/parse-recipes.mjs:24"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e34b8c6de1ab5308", "name": "Commented-code block (6 lines) in scripts/extract-pdf/generate-seed-ts.mjs:4", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/extract-pdf/generate-seed-ts.mjs:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3e200b81de31876b", "name": "Commented-code block (12 lines) in scripts/extract-pdf/taco-to-json.mjs:4", "shortDescription": {"text": "Commented-code block (12 lines) in scripts/extract-pdf/taco-to-json.mjs:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-287e9e03f5cbe15a", "name": "Commented-code block (7 lines) in Design 2.0/tweaks-panel.jsx:12", "shortDescription": {"text": "Commented-code block (7 lines) in Design 2.0/tweaks-panel.jsx:12"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-54912ec73a03851d", "name": "Commented-code block (5 lines) in mobile/src/state/AppContext.tsx:1192", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/state/AppContext.tsx:1192"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5ee9e47259a6b767", "name": "`fetch()` without try/.catch or AbortSignal \u2014 mobile/src/api/client.ts:91", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 mobile/src/api/client.ts:91"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-46df75ba414a254b", "name": "Commented-code block (5 lines) in mobile/src/screens/VoiceScreen.tsx:1", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/screens/VoiceScreen.tsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2bc861c2a203b822", "name": "Commented-code block (6 lines) in mobile/src/screens/ProgressScreen.tsx:456", "shortDescription": {"text": "Commented-code block (6 lines) in mobile/src/screens/ProgressScreen.tsx:456"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4776f0adb8c889c5", "name": "Commented-code block (5 lines) in mobile/src/screens/ProfileScreen.tsx:45", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/screens/ProfileScreen.tsx:45"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-df98cec8a36d20eb", "name": "Commented-code block (6 lines) in mobile/src/screens/HomeScreen.tsx:440", "shortDescription": {"text": "Commented-code block (6 lines) in mobile/src/screens/HomeScreen.tsx:440"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5f5f88bc1c4e0c5a", "name": "Commented-code block (6 lines) in mobile/src/components/SpeedGauge.tsx:3", "shortDescription": {"text": "Commented-code block (6 lines) in mobile/src/components/SpeedGauge.tsx:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b3d795aeb5d08b0e", "name": "Commented-code block (6 lines) in mobile/src/components/LuAvatar.tsx:17", "shortDescription": {"text": "Commented-code block (6 lines) in mobile/src/components/LuAvatar.tsx:17"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d456d968d073ec13", "name": "Commented-code block (5 lines) in mobile/src/components/motion.tsx:5", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/components/motion.tsx:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e45bcd2258046a46", "name": "Commented-code block (5 lines) in mobile/src/components/NotificationsModal.tsx:1", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/components/NotificationsModal.tsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-38ee7eabfc243d8f", "name": "Commented-code block (5 lines) in mobile/src/components/AnimalSlider.tsx:3", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/components/AnimalSlider.tsx:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-752dc551f50ea182", "name": "Commented-code block (5 lines) in mobile/src/components/ShareProgressModal.tsx:4", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/components/ShareProgressModal.tsx:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c02bef71689f40dd", "name": "Commented-code block (5 lines) in mobile/src/components/OptionCard.tsx:3", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/components/OptionCard.tsx:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8984142d8043e955", "name": "Commented-code block (5 lines) in mobile/src/components/DateStrip.tsx:8", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/components/DateStrip.tsx:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4a807f863686cdac", "name": "Commented-code block (5 lines) in mobile/src/storage/mealsConfig.ts:14", "shortDescription": {"text": "Commented-code block (5 lines) in mobile/src/storage/mealsConfig.ts:14"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ad2fee0f6d93c257", "name": "Commented-code block (5 lines) in backend/src/routes/extractRecipe.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/routes/extractRecipe.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-fad8ecd9ce962906", "name": "Commented-code block (6 lines) in backend/src/routes/transcribeMeal.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in backend/src/routes/transcribeMeal.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2eafc3188c36bb02", "name": "3 env vars used in code but missing from .env.example", "shortDescription": {"text": "3 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `DATABASE_URL`, `DPI`, `PDF_PATH`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9759fa1f4cdc6148", "name": "Dangling fetch: POST https://www.youtube.com/youtubei/v1/player (backend/scripts/debug-youtube.mjs:9)", "shortDescription": {"text": "Dangling fetch: POST https://www.youtube.com/youtubei/v1/player (backend/scripts/debug-youtube.mjs:9)"}, "fullDescription": {"text": "`backend/scripts/debug-youtube.mjs:9` calls `POST https://www.youtube.com/youtubei/v1/player` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/www.youtube.com/youtubei/v1/player`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a92f43d7014f322c", "name": "Dangling fetch: POST https://www.youtube.com/youtubei/v1/player (backend/scripts/debug-youtube.mjs:45)", "shortDescription": {"text": "Dangling fetch: POST https://www.youtube.com/youtubei/v1/player (backend/scripts/debug-youtube.mjs:45)"}, "fullDescription": {"text": "`backend/scripts/debug-youtube.mjs:45` calls `POST https://www.youtube.com/youtubei/v1/player` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/www.youtube.com/youtubei/v1/player`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ca97ecabf518a7ff", "name": "Dangling fetch: GET https://www.tiktok.com/oembed?url=${encodeURIComponent(url)} (backend/src/routes/extractRecipe.js:21", "shortDescription": {"text": "Dangling fetch: GET https://www.tiktok.com/oembed?url=${encodeURIComponent(url)} (backend/src/routes/extractRecipe.js:212)"}, "fullDescription": {"text": "`backend/src/routes/extractRecipe.js:212` calls `GET https://www.tiktok.com/oembed?url=${encodeURIComponent(url)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/www.tiktok.com/oembed`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9c52c83df374ef3e", "name": "Dangling fetch: POST https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${encodeURIComponent(videoId)}&key=${a", "shortDescription": {"text": "Dangling fetch: POST https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${encodeURIComponent(videoId)}&key=${apiKey} (backend/src/routes/extractRecipe.js:244)"}, "fullDescription": {"text": "`backend/src/routes/extractRecipe.js:244` calls `POST https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${encodeURIComponent(videoId)}&key=${apiKey}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/www.googleapis.com/youtube/v3/videos`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-eb7d0b5d0b01fe62", "name": "Unused endpoint: USE /extract-recipe", "shortDescription": {"text": "Unused endpoint: USE /extract-recipe"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /extract-recipe` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a693f4173426467f", "name": "Unused endpoint: USE /analyze-food", "shortDescription": {"text": "Unused endpoint: USE /analyze-food"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /analyze-food` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ed523761442e1550", "name": "Unused endpoint: USE /chat", "shortDescription": {"text": "Unused endpoint: USE /chat"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /chat` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e5082c6df7a9bdb3", "name": "Unused endpoint: USE /insight", "shortDescription": {"text": "Unused endpoint: USE /insight"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /insight` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-deff43172ef19c7c", "name": "Unused endpoint: USE /day-review", "shortDescription": {"text": "Unused endpoint: USE /day-review"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /day-review` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a1ab861b562ca3d", "name": "Unused endpoint: USE /transcribe-meal", "shortDescription": {"text": "Unused endpoint: USE /transcribe-meal"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /transcribe-meal` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-43a28a1cded33384", "name": "Unused endpoint: USE /day-snapshot", "shortDescription": {"text": "Unused endpoint: USE /day-snapshot"}, "fullDescription": {"text": "`backend/src/index.js` declares `USE /day-snapshot` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`backend/src/routes/insight.js` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`backend/src/routes/daySnapshot.js` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/17818"}, "properties": {"repository": "RaphaelOM26/App-Nutri-Lu-2.0", "repoUrl": "https://github.com/RaphaelOM26/App-Nutri-Lu-2.0", "branch": "main"}, "results": [{"ruleId": "scanner-4aec4d46c0fc2658", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 claude-design-reference/onboarding/02-base-components.js:46"}, "properties": {"repobilityId": "de726a2b63560a35", "scanner": "scanner-primary", "fingerprint": "4aec4d46c0fc2658", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-33b364cce42d601f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 claude-design-reference/onboarding/07-onboarding-flow.jsx:86"}, "properties": {"repobilityId": "791e01bd8eb7520d", "scanner": "scanner-primary", "fingerprint": "33b364cce42d601f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7635b75e8e7fecbc", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 mobile/src/screens/ProgressScreen.tsx:307"}, "properties": {"repobilityId": "c343b33823b9d7cd", "scanner": "scanner-primary", "fingerprint": "7635b75e8e7fecbc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-3738c04c7ce03edc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 mobile/src/utils/notifications.ts:143"}, "properties": {"repobilityId": "4c73b89d641f9f4e", "scanner": "scanner-primary", "fingerprint": "3738c04c7ce03edc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-183753034450eecd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/db.js:51"}, "properties": {"repobilityId": "149cecece2f6d4d8", "scanner": "scanner-primary", "fingerprint": "183753034450eecd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b74a55f96eb9e099", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/index.js:75"}, "properties": {"repobilityId": "03d5d680343d7d14", "scanner": "scanner-primary", "fingerprint": "b74a55f96eb9e099", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-afaac8bd118d4b2e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/routes/analyzeFood.js:28"}, "properties": {"repobilityId": "30e62310f45d56cf", "scanner": "scanner-primary", "fingerprint": "afaac8bd118d4b2e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e489c2596eb5ef22", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/routes/extractRecipe.js:59"}, "properties": {"repobilityId": "ffeeccae9445877f", "scanner": "scanner-primary", "fingerprint": "e489c2596eb5ef22", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-9c6f5650cf749413", "level": "note", "message": {"text": "Very large file: scripts/extract-pdf/taco.ts (5927 lines)"}, "properties": {"repobilityId": "fc0211779ca13f0d", "scanner": "scanner-primary", "fingerprint": "9c6f5650cf749413", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-47187f75df4405b7", "level": "note", "message": {"text": "Very large file: mobile/src/state/AppContext.tsx (1576 lines)"}, "properties": {"repobilityId": "a2a7f9cd8399ca97", "scanner": "scanner-primary", "fingerprint": "47187f75df4405b7", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-221dcb46c8d224c4", "level": "note", "message": {"text": "Very large file: mobile/src/screens/RecipesScreen.tsx (1850 lines)"}, "properties": {"repobilityId": "499fa1913f28844e", "scanner": "scanner-primary", "fingerprint": "221dcb46c8d224c4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-50b955d54ed75bb5", "level": "note", "message": {"text": "Very large file: mobile/src/screens/ProgressScreen.tsx (1822 lines)"}, "properties": {"repobilityId": "9b0b0516012c46f0", "scanner": "scanner-primary", "fingerprint": "50b955d54ed75bb5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "dd019bf29eafdf2b", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "8d0a30025feb02e1", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "57cf5a4f29b20fd6", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "7d51938cc2b74b74", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "6b0af307a3cff565", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "a0d8346c782093da", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "45a615a04b6fa164", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "8a7e5d23b29a0f71", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-dae9813dfce98376", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/extract-pdf/parse-recipes.mjs:24"}, "properties": {"repobilityId": "fc4bf9569e5a7157", "scanner": "scanner-primary", "fingerprint": "dae9813dfce98376", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e34b8c6de1ab5308", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/extract-pdf/generate-seed-ts.mjs:4"}, "properties": {"repobilityId": "c2d74179138b253c", "scanner": "scanner-primary", "fingerprint": "e34b8c6de1ab5308", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3e200b81de31876b", "level": "none", "message": {"text": "Commented-code block (12 lines) in scripts/extract-pdf/taco-to-json.mjs:4"}, "properties": {"repobilityId": "0444c2110f91f5a1", "scanner": "scanner-primary", "fingerprint": "3e200b81de31876b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-287e9e03f5cbe15a", "level": "none", "message": {"text": "Commented-code block (7 lines) in Design 2.0/tweaks-panel.jsx:12"}, "properties": {"repobilityId": "d9ee0ecd2e8ca13f", "scanner": "scanner-primary", "fingerprint": "287e9e03f5cbe15a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-54912ec73a03851d", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/state/AppContext.tsx:1192"}, "properties": {"repobilityId": "a616127bbcb3acc6", "scanner": "scanner-primary", "fingerprint": "54912ec73a03851d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5ee9e47259a6b767", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 mobile/src/api/client.ts:91"}, "properties": {"repobilityId": "3a934f6943eb773d", "scanner": "scanner-primary", "fingerprint": "5ee9e47259a6b767", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-46df75ba414a254b", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/screens/VoiceScreen.tsx:1"}, "properties": {"repobilityId": "c52c96bbc1a069a2", "scanner": "scanner-primary", "fingerprint": "46df75ba414a254b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2bc861c2a203b822", "level": "none", "message": {"text": "Commented-code block (6 lines) in mobile/src/screens/ProgressScreen.tsx:456"}, "properties": {"repobilityId": "2345c4578e3ae629", "scanner": "scanner-primary", "fingerprint": "2bc861c2a203b822", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4776f0adb8c889c5", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/screens/ProfileScreen.tsx:45"}, "properties": {"repobilityId": "937978990e4c8a00", "scanner": "scanner-primary", "fingerprint": "4776f0adb8c889c5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-df98cec8a36d20eb", "level": "none", "message": {"text": "Commented-code block (6 lines) in mobile/src/screens/HomeScreen.tsx:440"}, "properties": {"repobilityId": "0fa155c05d37ae63", "scanner": "scanner-primary", "fingerprint": "df98cec8a36d20eb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5f5f88bc1c4e0c5a", "level": "none", "message": {"text": "Commented-code block (6 lines) in mobile/src/components/SpeedGauge.tsx:3"}, "properties": {"repobilityId": "967f305f1e6de4a2", "scanner": "scanner-primary", "fingerprint": "5f5f88bc1c4e0c5a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b3d795aeb5d08b0e", "level": "none", "message": {"text": "Commented-code block (6 lines) in mobile/src/components/LuAvatar.tsx:17"}, "properties": {"repobilityId": "284d4ffc9ea5c8ab", "scanner": "scanner-primary", "fingerprint": "b3d795aeb5d08b0e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d456d968d073ec13", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/components/motion.tsx:5"}, "properties": {"repobilityId": "d9b1d393ec5c3a66", "scanner": "scanner-primary", "fingerprint": "d456d968d073ec13", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e45bcd2258046a46", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/components/NotificationsModal.tsx:1"}, "properties": {"repobilityId": "88513dff0ac587cf", "scanner": "scanner-primary", "fingerprint": "e45bcd2258046a46", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-38ee7eabfc243d8f", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/components/AnimalSlider.tsx:3"}, "properties": {"repobilityId": "7d4d1e3d356e768c", "scanner": "scanner-primary", "fingerprint": "38ee7eabfc243d8f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-752dc551f50ea182", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/components/ShareProgressModal.tsx:4"}, "properties": {"repobilityId": "98f8b997b0115c31", "scanner": "scanner-primary", "fingerprint": "752dc551f50ea182", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c02bef71689f40dd", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/components/OptionCard.tsx:3"}, "properties": {"repobilityId": "11e2c5325f39b67f", "scanner": "scanner-primary", "fingerprint": "c02bef71689f40dd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8984142d8043e955", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/components/DateStrip.tsx:8"}, "properties": {"repobilityId": "b01a507bbb61146c", "scanner": "scanner-primary", "fingerprint": "8984142d8043e955", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4a807f863686cdac", "level": "none", "message": {"text": "Commented-code block (5 lines) in mobile/src/storage/mealsConfig.ts:14"}, "properties": {"repobilityId": "752970c0e54b44bd", "scanner": "scanner-primary", "fingerprint": "4a807f863686cdac", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ad2fee0f6d93c257", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/routes/extractRecipe.js:1"}, "properties": {"repobilityId": "c9ee3875878c4366", "scanner": "scanner-primary", "fingerprint": "ad2fee0f6d93c257", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fad8ecd9ce962906", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/src/routes/transcribeMeal.js:1"}, "properties": {"repobilityId": "3a8d57ea13de80dd", "scanner": "scanner-primary", "fingerprint": "fad8ecd9ce962906", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2eafc3188c36bb02", "level": "none", "message": {"text": "3 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "bd934ba112b02ffa", "scanner": "scanner-primary", "fingerprint": "2eafc3188c36bb02", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-9759fa1f4cdc6148", "level": "error", "message": {"text": "Dangling fetch: POST https://www.youtube.com/youtubei/v1/player (backend/scripts/debug-youtube.mjs:9)"}, "properties": {"repobilityId": "a97549b5d0e0d1ba", "scanner": "scanner-primary", "fingerprint": "9759fa1f4cdc6148", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a92f43d7014f322c", "level": "error", "message": {"text": "Dangling fetch: POST https://www.youtube.com/youtubei/v1/player (backend/scripts/debug-youtube.mjs:45)"}, "properties": {"repobilityId": "a9a91a4c41f9d16c", "scanner": "scanner-primary", "fingerprint": "a92f43d7014f322c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ca97ecabf518a7ff", "level": "error", "message": {"text": "Dangling fetch: GET https://www.tiktok.com/oembed?url=${encodeURIComponent(url)} (backend/src/routes/extractRecipe.js:212)"}, "properties": {"repobilityId": "3ca157abbc6130e0", "scanner": "scanner-primary", "fingerprint": "ca97ecabf518a7ff", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9c52c83df374ef3e", "level": "error", "message": {"text": "Dangling fetch: POST https://www.googleapis.com/youtube/v3/videos?part=snippet&id=${encodeURIComponent(videoId)}&key=${apiKey} (backend/src/routes/extractRecipe.js:244)"}, "properties": {"repobilityId": "60e58e7d86c6572a", "scanner": "scanner-primary", "fingerprint": "9c52c83df374ef3e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-eb7d0b5d0b01fe62", "level": "note", "message": {"text": "Unused endpoint: USE /extract-recipe"}, "properties": {"repobilityId": "d142752f2614638e", "scanner": "scanner-primary", "fingerprint": "eb7d0b5d0b01fe62", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a693f4173426467f", "level": "note", "message": {"text": "Unused endpoint: USE /analyze-food"}, "properties": {"repobilityId": "65e1ccfe4116ca8a", "scanner": "scanner-primary", "fingerprint": "a693f4173426467f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ed523761442e1550", "level": "note", "message": {"text": "Unused endpoint: USE /chat"}, "properties": {"repobilityId": "f9cb63a104a55d75", "scanner": "scanner-primary", "fingerprint": "ed523761442e1550", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e5082c6df7a9bdb3", "level": "note", "message": {"text": "Unused endpoint: USE /insight"}, "properties": {"repobilityId": "411a44af65eb6ed5", "scanner": "scanner-primary", "fingerprint": "e5082c6df7a9bdb3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-deff43172ef19c7c", "level": "note", "message": {"text": "Unused endpoint: USE /day-review"}, "properties": {"repobilityId": "ae2b4199de038cc1", "scanner": "scanner-primary", "fingerprint": "deff43172ef19c7c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a1ab861b562ca3d", "level": "note", "message": {"text": "Unused endpoint: USE /transcribe-meal"}, "properties": {"repobilityId": "5b93e1ee14d1e05e", "scanner": "scanner-primary", "fingerprint": "7a1ab861b562ca3d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-43a28a1cded33384", "level": "note", "message": {"text": "Unused endpoint: USE /day-snapshot"}, "properties": {"repobilityId": "d2520f936f693b51", "scanner": "scanner-primary", "fingerprint": "43a28a1cded33384", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "e1340ac20aee6d33", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "f5fc1ecb252947f0", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}