{"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-2870a710c1f7df3d", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-company-models.js:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-company-models.js:57"}, "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-1c970d80dadf34c9", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-glossary.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-glossary.js:24"}, "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-dee12b4aa0aa9f80", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-watchlist.js:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-watchlist.js:32"}, "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-8d9c429af614a4e6", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-engagement.js:34", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-engagement.js:34"}, "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-18f046d33abc75b3", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-push.js:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-push.js:46"}, "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-a9dd730f0569a449", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-picks.js:40", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-picks.js:40"}, "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-046df959029c4021", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-multi-kid.js:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-multi-kid.js:23"}, "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-641e0df03b96d504", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-games.js:27", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-games.js:27"}, "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-b2fda40bfceb470f", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-digest-schema.js:30", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-digest-schema.js:30"}, "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-e02c58be51a58c5e", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-mystery.js:47", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-mystery.js:47"}, "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-65e98d4d47522146", "name": "Stray `console.log` in TS/JS \u2014 scripts/inspect-db.js:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-db.js:20"}, "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-a8b184952f69d4bf", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-theme.js:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-theme.js:21"}, "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-46775b811541c302", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-weekly.js:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-weekly.js:46"}, "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-49e652ef2871f7a9", "name": "Stray `console.log` in TS/JS \u2014 scripts/run-schema.js:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/run-schema.js:33"}, "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-13c75eae96f7965d", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-multi-kid-emails.js:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-multi-kid-emails.js:25"}, "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-ceba7be1f592c57a", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-evening-email.js:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-evening-email.js:35"}, "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-fcaf036d905385bc", "name": "Stray `console.log` in TS/JS \u2014 src/games.js:94", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/games.js:94"}, "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-164d417c40a75837", "name": "Stray `console.log` in TS/JS \u2014 src/push.js:280", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/push.js:280"}, "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-2f0bf6dbc2f533e9", "name": "Stray `console.log` in TS/JS \u2014 src/generate.js:80", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/generate.js:80"}, "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-8e4c5ddede5ac7ec", "name": "Stray `console.log` in TS/JS \u2014 src/ai.js:1311", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/ai.js:1311"}, "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-6dcbc5a36ec25f80", "name": "Stray `console.log` in TS/JS \u2014 src/emails.js:833", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/emails.js:833"}, "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-1d57ce9edcf85456", "name": "Stray `console.log` in TS/JS \u2014 src/picks.js:334", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/picks.js:334"}, "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-419ab14299d7eb4f", "name": "Stray `console.log` in TS/JS \u2014 src/glossary-runtime.js:95", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/glossary-runtime.js:95"}, "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-86993a56d9047ac7", "name": "TODO/FIXME marker in shipping code \u2014 src/server.js:1408", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/server.js:1408"}, "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-008727718a4445df", "name": "Stray `console.log` in TS/JS \u2014 src/server.js:1382", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server.js:1382"}, "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-bcff40f92d99613f", "name": "Stray `console.log` in TS/JS \u2014 src/storage.js:181", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/storage.js:181"}, "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-23318586b499f2c6", "name": "Stray `console.log` in TS/JS \u2014 src/morning-run.js:77", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/morning-run.js:77"}, "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-a35c6a00f751880f", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b47f95adb1e541ad", "name": "Insecure pattern 'new_function_used' in scripts/test-mystery.js:204", "shortDescription": {"text": "Insecure pattern 'new_function_used' in scripts/test-mystery.js:204"}, "fullDescription": {"text": "Found a known-risky pattern (new_function_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-3f564ddc3e5b2407", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/engagement.js:182", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/engagement.js:182"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c5fc484c9d58b8f2", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/pwa.js:163", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/pwa.js:163"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9fe8c35893a6f58f", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/parent-delete-data.html:272", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/parent-delete-data.html:272"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c6dd36592d03df42", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/engagement-popups.js:41", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/engagement-popups.js:41"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8776d8028d9e630e", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games-preview.html:222", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games-preview.html:222"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b2f2e3c2573db8c4", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/landing.js:188", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/landing.js:188"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2256952ceb597540", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/price-is-right.js:61", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/price-is-right.js:61"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7bc9005a1d29ad1f", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/sunday-challenge.js:119", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/sunday-challenge.js:119"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2e92b1e795c0eb86", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/shared.js:59", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/shared.js:59"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4220a4686080aef7", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/compound.js:34", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/compound.js:34"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b70381f6bc1d870c", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/bull-bear.js:36", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/bull-bear.js:36"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cd02a76755c112f3", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/daily-challenge.js:74", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/daily-challenge.js:74"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-db72774e93dfd093", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/mystery-mover.js:233", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/mystery-mover.js:233"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b3b46c7fc9ce5a3e", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/time-machine.js:45", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/time-machine.js:45"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-70ce4d5ccdc38551", "name": "Insecure pattern 'direct_innerhtml_assignment' in public/games/match.js:37", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/match.js:37"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-843933be49e8a5bb", "name": "Possible secret in src/server.js", "shortDescription": {"text": "Possible secret in src/server.js"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "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-6da14de5b5696857", "name": "Very large file: src/ai.js (1784 lines)", "shortDescription": {"text": "Very large file: src/ai.js (1784 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-95a51ad92f2480c8", "name": "Very large file: src/emails.js (1301 lines)", "shortDescription": {"text": "Very large file: src/emails.js (1301 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-ee95f3b5ad1dbba6", "name": "Very large file: src/server.js (2439 lines)", "shortDescription": {"text": "Very large file: src/server.js (2439 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-3ed44aa61562294d", "name": "Very large file: src/template.js (2150 lines)", "shortDescription": {"text": "Very large file: src/template.js (2150 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-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "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 330 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 19 placeholder/mock markers across 10 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: license, 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 license, 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-8f39ed9f9fe4c7b5", "name": "Commented-code block (6 lines) in scripts/test-company-models.js:6", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-company-models.js:6"}, "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-0526590d2135ab9e", "name": "Commented-code block (6 lines) in scripts/test-glossary.js:3", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-glossary.js: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-9786b58967206e85", "name": "Commented-code block (7 lines) in scripts/test-watchlist.js:3", "shortDescription": {"text": "Commented-code block (7 lines) in scripts/test-watchlist.js: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-bea2070000fa180b", "name": "Commented-code block (6 lines) in scripts/test-engagement.js:117", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-engagement.js:117"}, "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-830da9e555b363c2", "name": "Commented-code block (6 lines) in scripts/test-push.js:5", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-push.js: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-b7ae381e16766d5f", "name": "Commented-code block (7 lines) in scripts/test-picks.js:8", "shortDescription": {"text": "Commented-code block (7 lines) in scripts/test-picks.js: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-3f1f19f650db807a", "name": "Commented-code block (9 lines) in scripts/test-digest-schema.js:6", "shortDescription": {"text": "Commented-code block (9 lines) in scripts/test-digest-schema.js:6"}, "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-8d04d57f4ed29545", "name": "Commented-code block (6 lines) in scripts/test-mystery.js:10", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-mystery.js:10"}, "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-0835a15d94cced74", "name": "Commented-code block (6 lines) in scripts/test-theme.js:3", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-theme.js: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-10c17de09acf7c5a", "name": "Commented-code block (7 lines) in scripts/test-weekly.js:9", "shortDescription": {"text": "Commented-code block (7 lines) in scripts/test-weekly.js:9"}, "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-4fa532f874eb2f67", "name": "Legacy-named symbol `sLegacy` in scripts/test-evening-email.js:345", "shortDescription": {"text": "Legacy-named symbol `sLegacy` in scripts/test-evening-email.js:345"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9b33bf95e3bd0ff6", "name": "Commented-code block (6 lines) in scripts/test-evening-email.js:3", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/test-evening-email.js: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-e4c6ba00dfa45077", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/engagement.js:119", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/engagement.js:119"}, "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-150da9843fdcc2bb", "name": "Commented-code block (6 lines) in public/sw.js:21", "shortDescription": {"text": "Commented-code block (6 lines) in public/sw.js:21"}, "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-e26b5a94506c4c57", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:166", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:166"}, "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-ed79dd22c9c0005d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/pwa.js:208", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/pwa.js:208"}, "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-3ead3366cbaf1e5d", "name": "Commented-code block (6 lines) in public/landing.js:44", "shortDescription": {"text": "Commented-code block (6 lines) in public/landing.js:44"}, "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-06e47ea0f84f54c0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 public/games/mystery-mover.js:167", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/games/mystery-mover.js:167"}, "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-4ffc0247a1789b17", "name": "Commented-code block (6 lines) in src/games.js:54", "shortDescription": {"text": "Commented-code block (6 lines) in src/games.js:54"}, "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-ff62072808ec5cf8", "name": "Commented-code block (7 lines) in src/weekly.js:8", "shortDescription": {"text": "Commented-code block (7 lines) in src/weekly.js: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-2d0d1736b4884e2b", "name": "Commented-code block (12 lines) in src/push.js:5", "shortDescription": {"text": "Commented-code block (12 lines) in src/push.js: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-01fb3718612df29e", "name": "Commented-code block (7 lines) in src/admin.js:51", "shortDescription": {"text": "Commented-code block (7 lines) in src/admin.js:51"}, "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-0601d7d12a673488", "name": "Commented-code block (6 lines) in src/generate.js:64", "shortDescription": {"text": "Commented-code block (6 lines) in src/generate.js:64"}, "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-393e6c9a3f67b777", "name": "Commented-code block (8 lines) in src/glossary.js:10", "shortDescription": {"text": "Commented-code block (8 lines) in src/glossary.js:10"}, "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-466fb9a99f28caec", "name": "Commented-code block (8 lines) in src/ai.js:18", "shortDescription": {"text": "Commented-code block (8 lines) in src/ai.js:18"}, "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-e0873f78475215de", "name": "Commented-code block (13 lines) in src/name-leak.js:7", "shortDescription": {"text": "Commented-code block (13 lines) in src/name-leak.js:7"}, "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-d0a03881022be139", "name": "Commented-code block (5 lines) in src/engagement.js:222", "shortDescription": {"text": "Commented-code block (5 lines) in src/engagement.js:222"}, "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-25ee01a50cfb272e", "name": "Commented-code block (6 lines) in src/db.js:23", "shortDescription": {"text": "Commented-code block (6 lines) in src/db.js:23"}, "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-b56e476546b9c2f6", "name": "Commented-code block (5 lines) in src/emails.js:28", "shortDescription": {"text": "Commented-code block (5 lines) in src/emails.js:28"}, "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-4d52ec1b716706e1", "name": "Commented-code block (5 lines) in src/auth.js:42", "shortDescription": {"text": "Commented-code block (5 lines) in src/auth.js:42"}, "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-d55648aede3c42a7", "name": "Commented-code block (5 lines) in src/progress-template.js:6", "shortDescription": {"text": "Commented-code block (5 lines) in src/progress-template.js:6"}, "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-e86e83c9f55e95dd", "name": "Commented-code block (27 lines) in src/picks.js:7", "shortDescription": {"text": "Commented-code block (27 lines) in src/picks.js:7"}, "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-6aaa8f92d8546309", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/picks.js:578", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/picks.js:578"}, "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-470ac8ba88833c6b", "name": "Commented-code block (5 lines) in src/watchlist.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/watchlist.js: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-3ea98969cb0b9ec8", "name": "Commented-code block (9 lines) in src/glossary-runtime.js:11", "shortDescription": {"text": "Commented-code block (9 lines) in src/glossary-runtime.js:11"}, "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-ac2c58232b5645cf", "name": "Commented-code block (5 lines) in src/digest-schema.js:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/digest-schema.js: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-ba20853634280719", "name": "Commented-code block (5 lines) in src/data.js:239", "shortDescription": {"text": "Commented-code block (5 lines) in src/data.js:239"}, "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-85c9c7de5e0c4816", "name": "Commented-code block (5 lines) in src/server.js:54", "shortDescription": {"text": "Commented-code block (5 lines) in src/server.js:54"}, "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-06b23bc557279c4e", "name": "Commented-code block (10 lines) in src/template.js:161", "shortDescription": {"text": "Commented-code block (10 lines) in src/template.js:161"}, "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-f2c4648a66164999", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/template.js:1942", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/template.js:1942"}, "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-6037524838a2b9b5", "name": "Commented-code block (6 lines) in src/storage.js:273", "shortDescription": {"text": "Commented-code block (6 lines) in src/storage.js:273"}, "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-c0e61ac797e4d8be", "name": "Commented-code block (5 lines) in src/calendar.js:22", "shortDescription": {"text": "Commented-code block (5 lines) in src/calendar.js:22"}, "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-ca77015886ce6620", "name": "Commented-code block (19 lines) in src/mystery.js:8", "shortDescription": {"text": "Commented-code block (19 lines) in src/mystery.js: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-d1770beace1bdba0", "name": "Commented-code block (5 lines) in src/morning-run.js:8", "shortDescription": {"text": "Commented-code block (5 lines) in src/morning-run.js: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-c2a09287e6a6ade1", "name": "Commented-code block (7 lines) in src/companies.js:10", "shortDescription": {"text": "Commented-code block (7 lines) in src/companies.js:10"}, "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-b0b5e7cb1208a7cd", "name": "13 env vars used in code but missing from .env.example", "shortDescription": {"text": "13 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_KEY`, `ALERT_SUCCESS_PING`, `ANTHROPIC_API_KEY`, `DATE_OVERRIDE`, `FMP_API_KEY`, `LAST_GENERATED`, `NODE_ENV`, `RESEND_WEBHOOK_SECRET` + 5 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a846b38e0742296", "name": "Dangling fetch: POST https://api.telegram.org/bot${token}/sendMessage (src/notify.js:36)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/sendMessage (src/notify.js:36)"}, "fullDescription": {"text": "`src/notify.js:36` calls `POST https://api.telegram.org/bot${token}/sendMessage` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/sendmessage`\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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`src/server.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}}, {"id": "scanner-7f553401f296cac6", "name": "Unused endpoint: GET /digest", "shortDescription": {"text": "Unused endpoint: GET /digest"}, "fullDescription": {"text": "`src/server.js` declares `GET /digest` 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-619853fd9a80f057", "name": "Unused endpoint: GET /progress", "shortDescription": {"text": "Unused endpoint: GET /progress"}, "fullDescription": {"text": "`src/server.js` declares `GET /progress` 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-ba791f4582f5e42c", "name": "Unused endpoint: GET /sample", "shortDescription": {"text": "Unused endpoint: GET /sample"}, "fullDescription": {"text": "`src/server.js` declares `GET /sample` 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-9daee89b78e9ceac", "name": "Unused endpoint: GET /privacy", "shortDescription": {"text": "Unused endpoint: GET /privacy"}, "fullDescription": {"text": "`src/server.js` declares `GET /privacy` 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-55838a84fe14beac", "name": "Unused endpoint: GET /parent/delete-data", "shortDescription": {"text": "Unused endpoint: GET /parent/delete-data"}, "fullDescription": {"text": "`src/server.js` declares `GET /parent/delete-data` 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-6a4dfcad3eb1618a", "name": "Unused endpoint: GET /login", "shortDescription": {"text": "Unused endpoint: GET /login"}, "fullDescription": {"text": "`src/server.js` declares `GET /login` 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-4451c490400c7b0a", "name": "Unused endpoint: GET /forgot-password", "shortDescription": {"text": "Unused endpoint: GET /forgot-password"}, "fullDescription": {"text": "`src/server.js` declares `GET /forgot-password` 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-3643f9843301e6ce", "name": "Unused endpoint: GET /reset-password", "shortDescription": {"text": "Unused endpoint: GET /reset-password"}, "fullDescription": {"text": "`src/server.js` declares `GET /reset-password` 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-200ab2e98a288506", "name": "Unused endpoint: POST /api/login", "shortDescription": {"text": "Unused endpoint: POST /api/login"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/login` 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-8355db56c2f7bd7b", "name": "Unused endpoint: GET /api/check-username", "shortDescription": {"text": "Unused endpoint: GET /api/check-username"}, "fullDescription": {"text": "`src/server.js` declares `GET /api/check-username` 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-a310d5b81aef3f4d", "name": "Unused endpoint: POST /api/forgot-password", "shortDescription": {"text": "Unused endpoint: POST /api/forgot-password"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/forgot-password` 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-96aa6a37afa1dbf3", "name": "Unused endpoint: POST /api/reset-password", "shortDescription": {"text": "Unused endpoint: POST /api/reset-password"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/reset-password` 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-1b4bc3e641888422", "name": "Unused endpoint: POST /api/watchlist", "shortDescription": {"text": "Unused endpoint: POST /api/watchlist"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/watchlist` 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-86b7d67df84487bb", "name": "Unused endpoint: POST /api/watchlist/save", "shortDescription": {"text": "Unused endpoint: POST /api/watchlist/save"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/watchlist/save` 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-4bb1527a3548424a", "name": "Unused endpoint: DELETE /api/watchlist/:ticker", "shortDescription": {"text": "Unused endpoint: DELETE /api/watchlist/:ticker"}, "fullDescription": {"text": "`src/server.js` declares `DELETE /api/watchlist/:ticker` 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-5a96c617c902a073", "name": "Unused endpoint: POST /api/watchlist/milestone", "shortDescription": {"text": "Unused endpoint: POST /api/watchlist/milestone"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/watchlist/milestone` 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-f95c9f619ddf7a60", "name": "Unused endpoint: POST /api/watchlist/offer", "shortDescription": {"text": "Unused endpoint: POST /api/watchlist/offer"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/watchlist/offer` 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-82a28f9274ee8f0c", "name": "Unused endpoint: GET /api/push/public-key", "shortDescription": {"text": "Unused endpoint: GET /api/push/public-key"}, "fullDescription": {"text": "`src/server.js` declares `GET /api/push/public-key` 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-c622e6243ccd6e0a", "name": "Unused endpoint: POST /api/push/subscribe", "shortDescription": {"text": "Unused endpoint: POST /api/push/subscribe"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/push/subscribe` 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-97cb8b976bfc0553", "name": "Unused endpoint: POST /api/push/unsubscribe", "shortDescription": {"text": "Unused endpoint: POST /api/push/unsubscribe"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/push/unsubscribe` 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-a4ba2a46bd4c1d8e", "name": "Unused endpoint: GET /api/verify", "shortDescription": {"text": "Unused endpoint: GET /api/verify"}, "fullDescription": {"text": "`src/server.js` declares `GET /api/verify` 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-bf68e2b89e9f9a20", "name": "Unused endpoint: GET /api/consent", "shortDescription": {"text": "Unused endpoint: GET /api/consent"}, "fullDescription": {"text": "`src/server.js` declares `GET /api/consent` 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-7198e6d1cb9eb4de", "name": "Unused endpoint: GET /api/add-child-consent", "shortDescription": {"text": "Unused endpoint: GET /api/add-child-consent"}, "fullDescription": {"text": "`src/server.js` declares `GET /api/add-child-consent` 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-e81ae50016d57304", "name": "Unused endpoint: POST /api/delete-data/request", "shortDescription": {"text": "Unused endpoint: POST /api/delete-data/request"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/delete-data/request` 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-fe12b2d177170333", "name": "Unused endpoint: POST /api/delete-data/children", "shortDescription": {"text": "Unused endpoint: POST /api/delete-data/children"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/delete-data/children` 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-6a8a42abe58bdefb", "name": "Unused endpoint: POST /api/delete-data", "shortDescription": {"text": "Unused endpoint: POST /api/delete-data"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/delete-data` 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-54a4c43fd2f24fee", "name": "Unused endpoint: POST /api/cron/send-digest", "shortDescription": {"text": "Unused endpoint: POST /api/cron/send-digest"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/cron/send-digest` 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-f0c67f00f487758e", "name": "Unused endpoint: POST /api/webhooks/resend", "shortDescription": {"text": "Unused endpoint: POST /api/webhooks/resend"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/webhooks/resend` 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-e8614df2893d241a", "name": "Unused endpoint: GET /generate", "shortDescription": {"text": "Unused endpoint: GET /generate"}, "fullDescription": {"text": "`src/server.js` declares `GET /generate` 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-953ec1a0ee6df50d", "name": "Unused endpoint: GET /admin", "shortDescription": {"text": "Unused endpoint: GET /admin"}, "fullDescription": {"text": "`src/server.js` declares `GET /admin` 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-d9da6c2372a22b54", "name": "Unused endpoint: POST /api/admin/glossary/:id/approve", "shortDescription": {"text": "Unused endpoint: POST /api/admin/glossary/:id/approve"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/admin/glossary/:id/approve` 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-d21b4eb92abae8a8", "name": "Unused endpoint: POST /api/admin/glossary/:id/reject", "shortDescription": {"text": "Unused endpoint: POST /api/admin/glossary/:id/reject"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/admin/glossary/:id/reject` 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-4756b4c4da7d2088", "name": "Unused endpoint: GET /api/health", "shortDescription": {"text": "Unused endpoint: GET /api/health"}, "fullDescription": {"text": "`src/server.js` declares `GET /api/health` 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-bb1b0971367cdd32", "name": "Unused endpoint: POST /api/cron/send-evening-recap", "shortDescription": {"text": "Unused endpoint: POST /api/cron/send-evening-recap"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/cron/send-evening-recap` 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-f3f1afba0fad7f83", "name": "Unused endpoint: POST /api/cron/send-push", "shortDescription": {"text": "Unused endpoint: POST /api/cron/send-push"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/cron/send-push` 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-1753274135f1db59", "name": "Unused endpoint: POST /api/cron/cleanup-abandoned", "shortDescription": {"text": "Unused endpoint: POST /api/cron/cleanup-abandoned"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/cron/cleanup-abandoned` 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-57f3285c275c078b", "name": "Unused endpoint: POST /api/cron/cleanup-inactive", "shortDescription": {"text": "Unused endpoint: POST /api/cron/cleanup-inactive"}, "fullDescription": {"text": "`src/server.js` declares `POST /api/cron/cleanup-inactive` 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/20507"}, "properties": {"repository": "SunnyD27/market-buzz-kids", "repoUrl": "https://github.com/SunnyD27/market-buzz-kids", "branch": "main"}, "results": [{"ruleId": "scanner-2870a710c1f7df3d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-company-models.js:57"}, "properties": {"repobilityId": "4ad6fd53a39115e2", "scanner": "scanner-primary", "fingerprint": "2870a710c1f7df3d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1c970d80dadf34c9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-glossary.js:24"}, "properties": {"repobilityId": "6c447a857f76a6d7", "scanner": "scanner-primary", "fingerprint": "1c970d80dadf34c9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-dee12b4aa0aa9f80", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-watchlist.js:32"}, "properties": {"repobilityId": "05227fde37dc7b3e", "scanner": "scanner-primary", "fingerprint": "dee12b4aa0aa9f80", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8d9c429af614a4e6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-engagement.js:34"}, "properties": {"repobilityId": "59756de9c5294e13", "scanner": "scanner-primary", "fingerprint": "8d9c429af614a4e6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-18f046d33abc75b3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-push.js:46"}, "properties": {"repobilityId": "baba531afb9710d6", "scanner": "scanner-primary", "fingerprint": "18f046d33abc75b3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a9dd730f0569a449", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-picks.js:40"}, "properties": {"repobilityId": "34ae4d2be0409f5b", "scanner": "scanner-primary", "fingerprint": "a9dd730f0569a449", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-046df959029c4021", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-multi-kid.js:23"}, "properties": {"repobilityId": "b10f7a597bc38f7b", "scanner": "scanner-primary", "fingerprint": "046df959029c4021", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-641e0df03b96d504", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-games.js:27"}, "properties": {"repobilityId": "1ce5d7e42d771f68", "scanner": "scanner-primary", "fingerprint": "641e0df03b96d504", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b2fda40bfceb470f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-digest-schema.js:30"}, "properties": {"repobilityId": "e3f7e4e112ec68e8", "scanner": "scanner-primary", "fingerprint": "b2fda40bfceb470f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e02c58be51a58c5e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-mystery.js:47"}, "properties": {"repobilityId": "af8376e4e433e332", "scanner": "scanner-primary", "fingerprint": "e02c58be51a58c5e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-65e98d4d47522146", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-db.js:20"}, "properties": {"repobilityId": "433ab5c6e86799cb", "scanner": "scanner-primary", "fingerprint": "65e98d4d47522146", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a8b184952f69d4bf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-theme.js:21"}, "properties": {"repobilityId": "3703b18662fc2abe", "scanner": "scanner-primary", "fingerprint": "a8b184952f69d4bf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-46775b811541c302", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-weekly.js:46"}, "properties": {"repobilityId": "e064b51d338674be", "scanner": "scanner-primary", "fingerprint": "46775b811541c302", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-49e652ef2871f7a9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/run-schema.js:33"}, "properties": {"repobilityId": "d4147e6fc3dfadd8", "scanner": "scanner-primary", "fingerprint": "49e652ef2871f7a9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-13c75eae96f7965d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-multi-kid-emails.js:25"}, "properties": {"repobilityId": "77a34672b72f8b01", "scanner": "scanner-primary", "fingerprint": "13c75eae96f7965d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ceba7be1f592c57a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-evening-email.js:35"}, "properties": {"repobilityId": "011ce92499f81d3a", "scanner": "scanner-primary", "fingerprint": "ceba7be1f592c57a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fcaf036d905385bc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/games.js:94"}, "properties": {"repobilityId": "fc8449c6011caefa", "scanner": "scanner-primary", "fingerprint": "fcaf036d905385bc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-164d417c40a75837", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/push.js:280"}, "properties": {"repobilityId": "be4033e9b12c2fde", "scanner": "scanner-primary", "fingerprint": "164d417c40a75837", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2f0bf6dbc2f533e9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/generate.js:80"}, "properties": {"repobilityId": "d5d871784776a068", "scanner": "scanner-primary", "fingerprint": "2f0bf6dbc2f533e9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8e4c5ddede5ac7ec", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/ai.js:1311"}, "properties": {"repobilityId": "769a84a0456e9d42", "scanner": "scanner-primary", "fingerprint": "8e4c5ddede5ac7ec", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6dcbc5a36ec25f80", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/emails.js:833"}, "properties": {"repobilityId": "34e7bde7aad40e32", "scanner": "scanner-primary", "fingerprint": "6dcbc5a36ec25f80", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1d57ce9edcf85456", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/picks.js:334"}, "properties": {"repobilityId": "38fa5d301ff25f16", "scanner": "scanner-primary", "fingerprint": "1d57ce9edcf85456", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-419ab14299d7eb4f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/glossary-runtime.js:95"}, "properties": {"repobilityId": "d06a2afb35306fa5", "scanner": "scanner-primary", "fingerprint": "419ab14299d7eb4f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-86993a56d9047ac7", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/server.js:1408"}, "properties": {"repobilityId": "ef0bd4229fc62ef1", "scanner": "scanner-primary", "fingerprint": "86993a56d9047ac7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-008727718a4445df", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server.js:1382"}, "properties": {"repobilityId": "51ec0d6adae748e2", "scanner": "scanner-primary", "fingerprint": "008727718a4445df", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bcff40f92d99613f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/storage.js:181"}, "properties": {"repobilityId": "d09b74995e9f500f", "scanner": "scanner-primary", "fingerprint": "bcff40f92d99613f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-23318586b499f2c6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/morning-run.js:77"}, "properties": {"repobilityId": "c602595906ed01ac", "scanner": "scanner-primary", "fingerprint": "23318586b499f2c6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a35c6a00f751880f", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-slim"}, "properties": {"repobilityId": "be924fbee382ebe0", "scanner": "scanner-primary", "fingerprint": "a35c6a00f751880f", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-b47f95adb1e541ad", "level": "error", "message": {"text": "Insecure pattern 'new_function_used' in scripts/test-mystery.js:204"}, "properties": {"repobilityId": "bdf4aee96ad49665", "scanner": "scanner-primary", "fingerprint": "b47f95adb1e541ad", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "new_function_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/test-mystery.js"}, "region": {"startLine": 204}}}]}, {"ruleId": "scanner-3f564ddc3e5b2407", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/engagement.js:182"}, "properties": {"repobilityId": "dcd67c5e57712c4c", "scanner": "scanner-primary", "fingerprint": "3f564ddc3e5b2407", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/engagement.js"}, "region": {"startLine": 182}}}]}, {"ruleId": "scanner-c5fc484c9d58b8f2", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/pwa.js:163"}, "properties": {"repobilityId": "056abccc094073bd", "scanner": "scanner-primary", "fingerprint": "c5fc484c9d58b8f2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/pwa.js"}, "region": {"startLine": 163}}}]}, {"ruleId": "scanner-9fe8c35893a6f58f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/parent-delete-data.html:272"}, "properties": {"repobilityId": "69cdb0cb9bb9b8cd", "scanner": "scanner-primary", "fingerprint": "9fe8c35893a6f58f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/parent-delete-data.html"}, "region": {"startLine": 272}}}]}, {"ruleId": "scanner-c6dd36592d03df42", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/engagement-popups.js:41"}, "properties": {"repobilityId": "78a1ce07a7deaff9", "scanner": "scanner-primary", "fingerprint": "c6dd36592d03df42", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/engagement-popups.js"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-8776d8028d9e630e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games-preview.html:222"}, "properties": {"repobilityId": "3ba9d143bcb7fcf8", "scanner": "scanner-primary", "fingerprint": "8776d8028d9e630e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games-preview.html"}, "region": {"startLine": 222}}}]}, {"ruleId": "scanner-b2f2e3c2573db8c4", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/landing.js:188"}, "properties": {"repobilityId": "67f0b782e482175d", "scanner": "scanner-primary", "fingerprint": "b2f2e3c2573db8c4", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/landing.js"}, "region": {"startLine": 188}}}]}, {"ruleId": "scanner-2256952ceb597540", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/price-is-right.js:61"}, "properties": {"repobilityId": "7e35aa96bedd27a8", "scanner": "scanner-primary", "fingerprint": "2256952ceb597540", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/price-is-right.js"}, "region": {"startLine": 61}}}]}, {"ruleId": "scanner-7bc9005a1d29ad1f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/sunday-challenge.js:119"}, "properties": {"repobilityId": "e339e2435f1f98d0", "scanner": "scanner-primary", "fingerprint": "7bc9005a1d29ad1f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/sunday-challenge.js"}, "region": {"startLine": 119}}}]}, {"ruleId": "scanner-2e92b1e795c0eb86", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/shared.js:59"}, "properties": {"repobilityId": "c9d40ac78968e2e8", "scanner": "scanner-primary", "fingerprint": "2e92b1e795c0eb86", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/shared.js"}, "region": {"startLine": 59}}}]}, {"ruleId": "scanner-4220a4686080aef7", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/compound.js:34"}, "properties": {"repobilityId": "494284ea470db1ff", "scanner": "scanner-primary", "fingerprint": "4220a4686080aef7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/compound.js"}, "region": {"startLine": 34}}}]}, {"ruleId": "scanner-b70381f6bc1d870c", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/bull-bear.js:36"}, "properties": {"repobilityId": "de691ace44021960", "scanner": "scanner-primary", "fingerprint": "b70381f6bc1d870c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/bull-bear.js"}, "region": {"startLine": 36}}}]}, {"ruleId": "scanner-cd02a76755c112f3", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/daily-challenge.js:74"}, "properties": {"repobilityId": "44df7e2c5f5b9a02", "scanner": "scanner-primary", "fingerprint": "cd02a76755c112f3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/daily-challenge.js"}, "region": {"startLine": 74}}}]}, {"ruleId": "scanner-db72774e93dfd093", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/mystery-mover.js:233"}, "properties": {"repobilityId": "a97b2cd20ee9cdb9", "scanner": "scanner-primary", "fingerprint": "db72774e93dfd093", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/mystery-mover.js"}, "region": {"startLine": 233}}}]}, {"ruleId": "scanner-b3b46c7fc9ce5a3e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/time-machine.js:45"}, "properties": {"repobilityId": "60930cd1919fb96c", "scanner": "scanner-primary", "fingerprint": "b3b46c7fc9ce5a3e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/time-machine.js"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-70ce4d5ccdc38551", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in public/games/match.js:37"}, "properties": {"repobilityId": "1810433113a5a15f", "scanner": "scanner-primary", "fingerprint": "70ce4d5ccdc38551", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "public/games/match.js"}, "region": {"startLine": 37}}}]}, {"ruleId": "scanner-843933be49e8a5bb", "level": "error", "message": {"text": "Possible secret in src/server.js"}, "properties": {"repobilityId": "4f56df3702e89a57", "scanner": "scanner-primary", "fingerprint": "843933be49e8a5bb", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/server.js"}, "region": {"startLine": 888}}}]}, {"ruleId": "scanner-843933be49e8a5bb", "level": "error", "message": {"text": "Possible secret in src/server.js"}, "properties": {"repobilityId": "4f56df3702e89a57", "scanner": "scanner-primary", "fingerprint": "843933be49e8a5bb", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/server.js"}, "region": {"startLine": 890}}}]}, {"ruleId": "scanner-843933be49e8a5bb", "level": "error", "message": {"text": "Possible secret in src/server.js"}, "properties": {"repobilityId": "4f56df3702e89a57", "scanner": "scanner-primary", "fingerprint": "843933be49e8a5bb", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/server.js"}, "region": {"startLine": 893}}}]}, {"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-6da14de5b5696857", "level": "note", "message": {"text": "Very large file: src/ai.js (1784 lines)"}, "properties": {"repobilityId": "f79b24618b33f795", "scanner": "scanner-primary", "fingerprint": "6da14de5b5696857", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-95a51ad92f2480c8", "level": "note", "message": {"text": "Very large file: src/emails.js (1301 lines)"}, "properties": {"repobilityId": "564a31ea90be609b", "scanner": "scanner-primary", "fingerprint": "95a51ad92f2480c8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ee95f3b5ad1dbba6", "level": "note", "message": {"text": "Very large file: src/server.js (2439 lines)"}, "properties": {"repobilityId": "ba2a4d84798285f4", "scanner": "scanner-primary", "fingerprint": "ee95f3b5ad1dbba6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-3ed44aa61562294d", "level": "note", "message": {"text": "Very large file: src/template.js (2150 lines)"}, "properties": {"repobilityId": "52883ad092f24f52", "scanner": "scanner-primary", "fingerprint": "3ed44aa61562294d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "9e7b55cc4e9a003a", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "83bd400d76664e0b", "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": "7034dd8bea0eb998", "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": "295c4fcea53978d7", "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": "d1b0d07cd3c0b1e5", "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": "832e80518e955a84", "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": "e5e03eeb1a26cba1", "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": "bbe40ce7185dde3c", "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": "d19f5c41e5446a56", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8f39ed9f9fe4c7b5", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-company-models.js:6"}, "properties": {"repobilityId": "532376cce5f2c86e", "scanner": "scanner-primary", "fingerprint": "8f39ed9f9fe4c7b5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0526590d2135ab9e", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-glossary.js:3"}, "properties": {"repobilityId": "670d637c0b02cf19", "scanner": "scanner-primary", "fingerprint": "0526590d2135ab9e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9786b58967206e85", "level": "none", "message": {"text": "Commented-code block (7 lines) in scripts/test-watchlist.js:3"}, "properties": {"repobilityId": "80a780cf9f0cbf7a", "scanner": "scanner-primary", "fingerprint": "9786b58967206e85", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bea2070000fa180b", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-engagement.js:117"}, "properties": {"repobilityId": "ea7e257eee7ba8e2", "scanner": "scanner-primary", "fingerprint": "bea2070000fa180b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-830da9e555b363c2", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-push.js:5"}, "properties": {"repobilityId": "09cc39970265aece", "scanner": "scanner-primary", "fingerprint": "830da9e555b363c2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b7ae381e16766d5f", "level": "none", "message": {"text": "Commented-code block (7 lines) in scripts/test-picks.js:8"}, "properties": {"repobilityId": "e9bcd5554143fc30", "scanner": "scanner-primary", "fingerprint": "b7ae381e16766d5f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3f1f19f650db807a", "level": "none", "message": {"text": "Commented-code block (9 lines) in scripts/test-digest-schema.js:6"}, "properties": {"repobilityId": "20314baef0d4b92f", "scanner": "scanner-primary", "fingerprint": "3f1f19f650db807a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8d04d57f4ed29545", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-mystery.js:10"}, "properties": {"repobilityId": "5eaa1b7b7c4b536e", "scanner": "scanner-primary", "fingerprint": "8d04d57f4ed29545", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0835a15d94cced74", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-theme.js:3"}, "properties": {"repobilityId": "27a2996d57713f7c", "scanner": "scanner-primary", "fingerprint": "0835a15d94cced74", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-10c17de09acf7c5a", "level": "none", "message": {"text": "Commented-code block (7 lines) in scripts/test-weekly.js:9"}, "properties": {"repobilityId": "94a66ca0b91fcc03", "scanner": "scanner-primary", "fingerprint": "10c17de09acf7c5a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4fa532f874eb2f67", "level": "note", "message": {"text": "Legacy-named symbol `sLegacy` in scripts/test-evening-email.js:345"}, "properties": {"repobilityId": "8323120ea7d8411c", "scanner": "scanner-primary", "fingerprint": "4fa532f874eb2f67", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-9b33bf95e3bd0ff6", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/test-evening-email.js:3"}, "properties": {"repobilityId": "9b534a88f399943b", "scanner": "scanner-primary", "fingerprint": "9b33bf95e3bd0ff6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e4c6ba00dfa45077", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/engagement.js:119"}, "properties": {"repobilityId": "d7df83571c3d8579", "scanner": "scanner-primary", "fingerprint": "e4c6ba00dfa45077", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-150da9843fdcc2bb", "level": "none", "message": {"text": "Commented-code block (6 lines) in public/sw.js:21"}, "properties": {"repobilityId": "56225ec9c19ffc1e", "scanner": "scanner-primary", "fingerprint": "150da9843fdcc2bb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e26b5a94506c4c57", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/sw.js:166"}, "properties": {"repobilityId": "80485aad9dcbd8ee", "scanner": "scanner-primary", "fingerprint": "e26b5a94506c4c57", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ed79dd22c9c0005d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/pwa.js:208"}, "properties": {"repobilityId": "49d382ae48aa387c", "scanner": "scanner-primary", "fingerprint": "ed79dd22c9c0005d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3ead3366cbaf1e5d", "level": "none", "message": {"text": "Commented-code block (6 lines) in public/landing.js:44"}, "properties": {"repobilityId": "9a4ec56d4324e247", "scanner": "scanner-primary", "fingerprint": "3ead3366cbaf1e5d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-06e47ea0f84f54c0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 public/games/mystery-mover.js:167"}, "properties": {"repobilityId": "d4403f859b35d5c1", "scanner": "scanner-primary", "fingerprint": "06e47ea0f84f54c0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4ffc0247a1789b17", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/games.js:54"}, "properties": {"repobilityId": "5d1f684cc9c09444", "scanner": "scanner-primary", "fingerprint": "4ffc0247a1789b17", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ff62072808ec5cf8", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/weekly.js:8"}, "properties": {"repobilityId": "92ebe9768a12f5fd", "scanner": "scanner-primary", "fingerprint": "ff62072808ec5cf8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2d0d1736b4884e2b", "level": "none", "message": {"text": "Commented-code block (12 lines) in src/push.js:5"}, "properties": {"repobilityId": "bc7ba75daa8ac094", "scanner": "scanner-primary", "fingerprint": "2d0d1736b4884e2b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-01fb3718612df29e", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/admin.js:51"}, "properties": {"repobilityId": "074e23f5b0d6da5e", "scanner": "scanner-primary", "fingerprint": "01fb3718612df29e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0601d7d12a673488", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/generate.js:64"}, "properties": {"repobilityId": "4e42de9176183624", "scanner": "scanner-primary", "fingerprint": "0601d7d12a673488", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-393e6c9a3f67b777", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/glossary.js:10"}, "properties": {"repobilityId": "6ac6795a3a9e75b6", "scanner": "scanner-primary", "fingerprint": "393e6c9a3f67b777", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-466fb9a99f28caec", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/ai.js:18"}, "properties": {"repobilityId": "5a09da0d1eda64f6", "scanner": "scanner-primary", "fingerprint": "466fb9a99f28caec", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e0873f78475215de", "level": "none", "message": {"text": "Commented-code block (13 lines) in src/name-leak.js:7"}, "properties": {"repobilityId": "606d4a510a318143", "scanner": "scanner-primary", "fingerprint": "e0873f78475215de", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d0a03881022be139", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/engagement.js:222"}, "properties": {"repobilityId": "a5a01e88574f960d", "scanner": "scanner-primary", "fingerprint": "d0a03881022be139", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-25ee01a50cfb272e", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/db.js:23"}, "properties": {"repobilityId": "d8d48436c3f112bc", "scanner": "scanner-primary", "fingerprint": "25ee01a50cfb272e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b56e476546b9c2f6", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/emails.js:28"}, "properties": {"repobilityId": "884f792a02c8c602", "scanner": "scanner-primary", "fingerprint": "b56e476546b9c2f6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4d52ec1b716706e1", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/auth.js:42"}, "properties": {"repobilityId": "97ce6e37388a8083", "scanner": "scanner-primary", "fingerprint": "4d52ec1b716706e1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d55648aede3c42a7", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/progress-template.js:6"}, "properties": {"repobilityId": "db1e7bce2e7a9dce", "scanner": "scanner-primary", "fingerprint": "d55648aede3c42a7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e86e83c9f55e95dd", "level": "none", "message": {"text": "Commented-code block (27 lines) in src/picks.js:7"}, "properties": {"repobilityId": "21d25ce4318dd58b", "scanner": "scanner-primary", "fingerprint": "e86e83c9f55e95dd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6aaa8f92d8546309", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/picks.js:578"}, "properties": {"repobilityId": "244d292739686576", "scanner": "scanner-primary", "fingerprint": "6aaa8f92d8546309", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-470ac8ba88833c6b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/watchlist.js:3"}, "properties": {"repobilityId": "4dff4a36d51dd978", "scanner": "scanner-primary", "fingerprint": "470ac8ba88833c6b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3ea98969cb0b9ec8", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/glossary-runtime.js:11"}, "properties": {"repobilityId": "c6c74eb6366c907d", "scanner": "scanner-primary", "fingerprint": "3ea98969cb0b9ec8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ac2c58232b5645cf", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/digest-schema.js:3"}, "properties": {"repobilityId": "35426d740e16efa2", "scanner": "scanner-primary", "fingerprint": "ac2c58232b5645cf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ba20853634280719", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/data.js:239"}, "properties": {"repobilityId": "77e5a0db6f2074d8", "scanner": "scanner-primary", "fingerprint": "ba20853634280719", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-85c9c7de5e0c4816", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server.js:54"}, "properties": {"repobilityId": "993021662a01e541", "scanner": "scanner-primary", "fingerprint": "85c9c7de5e0c4816", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-06b23bc557279c4e", "level": "none", "message": {"text": "Commented-code block (10 lines) in src/template.js:161"}, "properties": {"repobilityId": "8214b24fad841221", "scanner": "scanner-primary", "fingerprint": "06b23bc557279c4e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f2c4648a66164999", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/template.js:1942"}, "properties": {"repobilityId": "45721d7f9c46f75a", "scanner": "scanner-primary", "fingerprint": "f2c4648a66164999", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6037524838a2b9b5", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/storage.js:273"}, "properties": {"repobilityId": "6896669854ab87f5", "scanner": "scanner-primary", "fingerprint": "6037524838a2b9b5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c0e61ac797e4d8be", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/calendar.js:22"}, "properties": {"repobilityId": "81a93cac6cb713c5", "scanner": "scanner-primary", "fingerprint": "c0e61ac797e4d8be", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ca77015886ce6620", "level": "none", "message": {"text": "Commented-code block (19 lines) in src/mystery.js:8"}, "properties": {"repobilityId": "e2961078744ed31b", "scanner": "scanner-primary", "fingerprint": "ca77015886ce6620", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d1770beace1bdba0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/morning-run.js:8"}, "properties": {"repobilityId": "40a08bbd2534596c", "scanner": "scanner-primary", "fingerprint": "d1770beace1bdba0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c2a09287e6a6ade1", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/companies.js:10"}, "properties": {"repobilityId": "27e7e3d0a700722a", "scanner": "scanner-primary", "fingerprint": "c2a09287e6a6ade1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b0b5e7cb1208a7cd", "level": "note", "message": {"text": "13 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "2737b8666c1f7eeb", "scanner": "scanner-primary", "fingerprint": "b0b5e7cb1208a7cd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-7a846b38e0742296", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/sendMessage (src/notify.js:36)"}, "properties": {"repobilityId": "50fb665c6794c1db", "scanner": "scanner-primary", "fingerprint": "7a846b38e0742296", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "c6cc29b21f64b855", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7f553401f296cac6", "level": "note", "message": {"text": "Unused endpoint: GET /digest"}, "properties": {"repobilityId": "d0e2d64978bf1161", "scanner": "scanner-primary", "fingerprint": "7f553401f296cac6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-619853fd9a80f057", "level": "note", "message": {"text": "Unused endpoint: GET /progress"}, "properties": {"repobilityId": "4d8b75f019f0d39b", "scanner": "scanner-primary", "fingerprint": "619853fd9a80f057", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ba791f4582f5e42c", "level": "note", "message": {"text": "Unused endpoint: GET /sample"}, "properties": {"repobilityId": "1296a0fac2ff6f58", "scanner": "scanner-primary", "fingerprint": "ba791f4582f5e42c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9daee89b78e9ceac", "level": "note", "message": {"text": "Unused endpoint: GET /privacy"}, "properties": {"repobilityId": "4dc74206a6e13489", "scanner": "scanner-primary", "fingerprint": "9daee89b78e9ceac", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-55838a84fe14beac", "level": "note", "message": {"text": "Unused endpoint: GET /parent/delete-data"}, "properties": {"repobilityId": "39042948ea62fa43", "scanner": "scanner-primary", "fingerprint": "55838a84fe14beac", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6a4dfcad3eb1618a", "level": "note", "message": {"text": "Unused endpoint: GET /login"}, "properties": {"repobilityId": "3b41d1b7347ba152", "scanner": "scanner-primary", "fingerprint": "6a4dfcad3eb1618a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4451c490400c7b0a", "level": "note", "message": {"text": "Unused endpoint: GET /forgot-password"}, "properties": {"repobilityId": "f1b6804cf3f815a8", "scanner": "scanner-primary", "fingerprint": "4451c490400c7b0a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3643f9843301e6ce", "level": "note", "message": {"text": "Unused endpoint: GET /reset-password"}, "properties": {"repobilityId": "2d99b6ea70175b38", "scanner": "scanner-primary", "fingerprint": "3643f9843301e6ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-200ab2e98a288506", "level": "note", "message": {"text": "Unused endpoint: POST /api/login"}, "properties": {"repobilityId": "5788b1d6c824e6ac", "scanner": "scanner-primary", "fingerprint": "200ab2e98a288506", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8355db56c2f7bd7b", "level": "note", "message": {"text": "Unused endpoint: GET /api/check-username"}, "properties": {"repobilityId": "c307d9f76b0c6d92", "scanner": "scanner-primary", "fingerprint": "8355db56c2f7bd7b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a310d5b81aef3f4d", "level": "note", "message": {"text": "Unused endpoint: POST /api/forgot-password"}, "properties": {"repobilityId": "5725bcc90d5521b8", "scanner": "scanner-primary", "fingerprint": "a310d5b81aef3f4d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-96aa6a37afa1dbf3", "level": "note", "message": {"text": "Unused endpoint: POST /api/reset-password"}, "properties": {"repobilityId": "f34b4a75ef79d5bf", "scanner": "scanner-primary", "fingerprint": "96aa6a37afa1dbf3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1b4bc3e641888422", "level": "note", "message": {"text": "Unused endpoint: POST /api/watchlist"}, "properties": {"repobilityId": "30dc850a5d2fd2c4", "scanner": "scanner-primary", "fingerprint": "1b4bc3e641888422", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-86b7d67df84487bb", "level": "note", "message": {"text": "Unused endpoint: POST /api/watchlist/save"}, "properties": {"repobilityId": "c42b17481b25407c", "scanner": "scanner-primary", "fingerprint": "86b7d67df84487bb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4bb1527a3548424a", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/watchlist/:ticker"}, "properties": {"repobilityId": "b0b592068a988eb0", "scanner": "scanner-primary", "fingerprint": "4bb1527a3548424a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5a96c617c902a073", "level": "note", "message": {"text": "Unused endpoint: POST /api/watchlist/milestone"}, "properties": {"repobilityId": "e7d97b7ebb986c0a", "scanner": "scanner-primary", "fingerprint": "5a96c617c902a073", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f95c9f619ddf7a60", "level": "note", "message": {"text": "Unused endpoint: POST /api/watchlist/offer"}, "properties": {"repobilityId": "689ad5357d9fe473", "scanner": "scanner-primary", "fingerprint": "f95c9f619ddf7a60", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-82a28f9274ee8f0c", "level": "note", "message": {"text": "Unused endpoint: GET /api/push/public-key"}, "properties": {"repobilityId": "1459e3d8d8064453", "scanner": "scanner-primary", "fingerprint": "82a28f9274ee8f0c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c622e6243ccd6e0a", "level": "note", "message": {"text": "Unused endpoint: POST /api/push/subscribe"}, "properties": {"repobilityId": "d69b6799847e3b03", "scanner": "scanner-primary", "fingerprint": "c622e6243ccd6e0a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-97cb8b976bfc0553", "level": "note", "message": {"text": "Unused endpoint: POST /api/push/unsubscribe"}, "properties": {"repobilityId": "b0489a270e4083f5", "scanner": "scanner-primary", "fingerprint": "97cb8b976bfc0553", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a4ba2a46bd4c1d8e", "level": "note", "message": {"text": "Unused endpoint: GET /api/verify"}, "properties": {"repobilityId": "5faf0721129e1841", "scanner": "scanner-primary", "fingerprint": "a4ba2a46bd4c1d8e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bf68e2b89e9f9a20", "level": "note", "message": {"text": "Unused endpoint: GET /api/consent"}, "properties": {"repobilityId": "9ab94524bff07bff", "scanner": "scanner-primary", "fingerprint": "bf68e2b89e9f9a20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7198e6d1cb9eb4de", "level": "note", "message": {"text": "Unused endpoint: GET /api/add-child-consent"}, "properties": {"repobilityId": "6db14d5cd41d03a4", "scanner": "scanner-primary", "fingerprint": "7198e6d1cb9eb4de", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e81ae50016d57304", "level": "note", "message": {"text": "Unused endpoint: POST /api/delete-data/request"}, "properties": {"repobilityId": "20bb712abbd7cba2", "scanner": "scanner-primary", "fingerprint": "e81ae50016d57304", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fe12b2d177170333", "level": "note", "message": {"text": "Unused endpoint: POST /api/delete-data/children"}, "properties": {"repobilityId": "c93f83876904ca66", "scanner": "scanner-primary", "fingerprint": "fe12b2d177170333", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6a8a42abe58bdefb", "level": "note", "message": {"text": "Unused endpoint: POST /api/delete-data"}, "properties": {"repobilityId": "2ddf0d559b4e7b50", "scanner": "scanner-primary", "fingerprint": "6a8a42abe58bdefb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-54a4c43fd2f24fee", "level": "note", "message": {"text": "Unused endpoint: POST /api/cron/send-digest"}, "properties": {"repobilityId": "dd37f9f4b4293d58", "scanner": "scanner-primary", "fingerprint": "54a4c43fd2f24fee", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f0c67f00f487758e", "level": "note", "message": {"text": "Unused endpoint: POST /api/webhooks/resend"}, "properties": {"repobilityId": "1722a1379f0cacfc", "scanner": "scanner-primary", "fingerprint": "f0c67f00f487758e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e8614df2893d241a", "level": "note", "message": {"text": "Unused endpoint: GET /generate"}, "properties": {"repobilityId": "0769174e778a5d92", "scanner": "scanner-primary", "fingerprint": "e8614df2893d241a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-953ec1a0ee6df50d", "level": "note", "message": {"text": "Unused endpoint: GET /admin"}, "properties": {"repobilityId": "79fd3fb76c905b5d", "scanner": "scanner-primary", "fingerprint": "953ec1a0ee6df50d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d9da6c2372a22b54", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/glossary/:id/approve"}, "properties": {"repobilityId": "73f2e13b87759c20", "scanner": "scanner-primary", "fingerprint": "d9da6c2372a22b54", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d21b4eb92abae8a8", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/glossary/:id/reject"}, "properties": {"repobilityId": "532f0544961d0a9a", "scanner": "scanner-primary", "fingerprint": "d21b4eb92abae8a8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4756b4c4da7d2088", "level": "note", "message": {"text": "Unused endpoint: GET /api/health"}, "properties": {"repobilityId": "45bf586efbfc4365", "scanner": "scanner-primary", "fingerprint": "4756b4c4da7d2088", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bb1b0971367cdd32", "level": "note", "message": {"text": "Unused endpoint: POST /api/cron/send-evening-recap"}, "properties": {"repobilityId": "14294729149d2581", "scanner": "scanner-primary", "fingerprint": "bb1b0971367cdd32", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f3f1afba0fad7f83", "level": "note", "message": {"text": "Unused endpoint: POST /api/cron/send-push"}, "properties": {"repobilityId": "e03368ce1512229f", "scanner": "scanner-primary", "fingerprint": "f3f1afba0fad7f83", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1753274135f1db59", "level": "note", "message": {"text": "Unused endpoint: POST /api/cron/cleanup-abandoned"}, "properties": {"repobilityId": "c5ff5ef9d345cd34", "scanner": "scanner-primary", "fingerprint": "1753274135f1db59", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-57f3285c275c078b", "level": "note", "message": {"text": "Unused endpoint: POST /api/cron/cleanup-inactive"}, "properties": {"repobilityId": "b184a1cfa5b6de5e", "scanner": "scanner-primary", "fingerprint": "57f3285c275c078b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}