{"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-58cf6d46faf92b7d", "name": "Icon-only button without accessible name \u2014 frontend/script.js:796", "shortDescription": {"text": "Icon-only button without accessible name \u2014 frontend/script.js:796"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1d707627c53e1cff", "name": "Stray `console.log` in TS/JS \u2014 frontend/script.js:82", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/script.js:82"}, "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-901666a2827bb722", "name": "Stray `console.log` in TS/JS \u2014 frontend/js/utils.js:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/js/utils.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-726853cee13167b3", "name": "Stray `console.log` in TS/JS \u2014 backend/config/cors.js:146", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/config/cors.js:146"}, "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-fb33a461c565068b", "name": "Stray `console.log` in TS/JS \u2014 backend/middleware/requestValidator.js:232", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/middleware/requestValidator.js:232"}, "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-d466a3297c8a54ec", "name": "Stray `console.log` in TS/JS \u2014 backend/middleware/requestLogger.js:102", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/middleware/requestLogger.js:102"}, "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-5d75f4455905a66a", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/migrate.js:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/migrate.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-7dabe078de573827", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/import-and-categorize-skills.js:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/import-and-categorize-skills.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-232af540ea16498a", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/seed-skills.js:135", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/seed-skills.js:135"}, "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-354a3e0edfd5f98e", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/seed-42-skills.js:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/seed-42-skills.js:22"}, "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-29dcf11950e4512a", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/generate-skill-sql.js:81", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/generate-skill-sql.js:81"}, "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-9515bb5996436a07", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/backfill-descriptions.js:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/backfill-descriptions.js:36"}, "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-cbb99566b8f4efa5", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/test-connection.js:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/test-connection.js:17"}, "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-3f916fc254108fa8", "name": "Stray `console.log` in TS/JS \u2014 backend/utils/creatorDigest.js:224", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/creatorDigest.js:224"}, "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-ac4c4f334a96c0f7", "name": "Stray `console.log` in TS/JS \u2014 backend/utils/email.js:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/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-58b48778b3691f87", "name": "Stray `console.log` in TS/JS \u2014 backend/utils/logger.js:10", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/logger.js:10"}, "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-a6c0bcdf805b7ebd", "name": "TODO/FIXME marker in shipping code \u2014 backend/utils/llmAdapter.js:141", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 backend/utils/llmAdapter.js:141"}, "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-074b4860217dde16", "name": "Stray `console.log` in TS/JS \u2014 backend/utils/llmAdapter.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/llmAdapter.js:13"}, "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-b22c42e019e10ad9", "name": "TODO/FIXME marker in shipping code \u2014 backend/routes/auth.js:223", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 backend/routes/auth.js:223"}, "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-750de24d8346b738", "name": "Stray `console.log` in TS/JS \u2014 backend/routes/skills.js:705", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/routes/skills.js:705"}, "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-079e04b5b7b8d3ed", "name": "Stray `console.log` in TS/JS \u2014 backend/db/seed-skills-on-startup.js:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/seed-skills-on-startup.js:18"}, "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-0bba9f840bbbef27", "name": "Stray `console.log` in TS/JS \u2014 backend/db/sqlite-adapter.js:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/sqlite-adapter.js:26"}, "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-d974d39e302fc057", "name": "Stray `console.log` in TS/JS \u2014 backend/db/init.js:119", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/init.js:119"}, "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-f2ff6253cf97dbfc", "name": "Stray `console.log` in TS/JS \u2014 backend/db/connectionPool.js:183", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/connectionPool.js:183"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-98c523aff735f30a", "name": "Docker base image is tag-pinned but not digest-pinned: node:18", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:18"}, "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-9710c8d059e53154", "name": "No frontend routes/components detected", "shortDescription": {"text": "No frontend routes/components detected"}, "fullDescription": {"text": "No React/Vue/Next routes were found. This is fine for backend-only repos."}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-206348a820cc5272", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/script.js:518", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/script.js:518"}, "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-22be419e59a8418e", "name": "Insecure pattern 'direct_innerhtml_assignment' in frontend/playground.html:1683", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/playground.html:1683"}, "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-0cdf74336728c563", "name": "Insecure pattern 'direct_innerhtml_assignment' in backend/server.js:286", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in backend/server.js:286"}, "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-6ec2740dae57a5d8", "name": "Insecure pattern 'cors_wildcard' in backend/server.js:131", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in backend/server.js:131"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9c87ea3179110852", "name": "Insecure pattern 'new_function_used' in backend/scripts/seed-skills.js:162", "shortDescription": {"text": "Insecure pattern 'new_function_used' in backend/scripts/seed-skills.js:162"}, "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-78ec093b8cab7de0", "name": "Insecure pattern 'new_function_used' in backend/scripts/seed-42-skills.js:130", "shortDescription": {"text": "Insecure pattern 'new_function_used' in backend/scripts/seed-42-skills.js:130"}, "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-e475ff7002659934", "name": "Insecure pattern 'new_function_used' in backend/scripts/generate-skill-sql.js:38", "shortDescription": {"text": "Insecure pattern 'new_function_used' in backend/scripts/generate-skill-sql.js:38"}, "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-9e316d1e4e1e4d33", "name": "Insecure pattern 'exec_used' in backend/db/sqlite-adapter.js:141", "shortDescription": {"text": "Insecure pattern 'exec_used' in backend/db/sqlite-adapter.js:141"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "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-887963f389585700", "name": "Very large file: frontend/script.js (9940 lines)", "shortDescription": {"text": "Very large file: frontend/script.js (9940 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-67287529926a71ac", "name": "Very large file: backend/utils/skillGeneration.js (1000 lines)", "shortDescription": {"text": "Very large file: backend/utils/skillGeneration.js (1000 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-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "8 tests / 43 src (ratio 0.19)."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3a092b5c39e242a1", "name": "Node manifest has dependencies but no lockfile: backend/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: backend/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "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 171 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 21 placeholder/mock markers across 6 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-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: ci, lockfile. 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": "low", "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-ea339e794b710506", "name": "Legacy-named symbol `preview_prompt_copy` in frontend/script.js:1088", "shortDescription": {"text": "Legacy-named symbol `preview_prompt_copy` in frontend/script.js:1088"}, "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-4e6dc7b28ec40c6e", "name": "Commented-code block (6 lines) in frontend/script.js:1598", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/script.js:1598"}, "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-10b61c939fa53081", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/script.js:404", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/script.js:404"}, "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-96f75b5a2c826e68", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/server.js:345", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/server.js:345"}, "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-36017d13bab87f4e", "name": "Commented-code block (5 lines) in backend/utils/auth.js:77", "shortDescription": {"text": "Commented-code block (5 lines) in backend/utils/auth.js:77"}, "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-cfee5d47fb16a78b", "name": "Commented-code block (5 lines) in backend/utils/skillGeneration.js:234", "shortDescription": {"text": "Commented-code block (5 lines) in backend/utils/skillGeneration.js:234"}, "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-c79aa1c5f0a5aff9", "name": "Commented-code block (5 lines) in backend/utils/backupScheduler.js:58", "shortDescription": {"text": "Commented-code block (5 lines) in backend/utils/backupScheduler.js:58"}, "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-b5cdbe69011ed29d", "name": "Commented-code block (5 lines) in backend/routes/playground.js:29", "shortDescription": {"text": "Commented-code block (5 lines) in backend/routes/playground.js:29"}, "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-4d309ccc3c843bae", "name": "Commented-code block (5 lines) in backend/routes/auth.js:27", "shortDescription": {"text": "Commented-code block (5 lines) in backend/routes/auth.js:27"}, "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-51070dad27d4e743", "name": "Commented-code block (5 lines) in backend/routes/forge.js:93", "shortDescription": {"text": "Commented-code block (5 lines) in backend/routes/forge.js:93"}, "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-b474b34392433652", "name": "Commented-code block (6 lines) in backend/routes/skills.js:23", "shortDescription": {"text": "Commented-code block (6 lines) in backend/routes/skills.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-05d8fe721848e118", "name": "Commented-code block (5 lines) in backend/db/sqlite-adapter.js:68", "shortDescription": {"text": "Commented-code block (5 lines) in backend/db/sqlite-adapter.js:68"}, "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-e2b2a7e79a37666c", "name": "Legacy-named symbol `probe_logs_old` in backend/db/init.js:120", "shortDescription": {"text": "Legacy-named symbol `probe_logs_old` in backend/db/init.js:120"}, "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-0c60cbe717a726da", "name": "Commented-code block (8 lines) in backend/db/init.js:9", "shortDescription": {"text": "Commented-code block (8 lines) in backend/db/init.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-d0b17c8c07a7421d", "name": "8 env vars used in code but missing from .env.example", "shortDescription": {"text": "8 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_KEY`, `ANTHROPIC_MODEL`, `DEEPSEEK_API_KEY`, `DEEPSEEK_MODEL`, `GEMINI_API_KEY`, `GEMINI_MODEL`, `POSTGRES_URI`, `REACT_APP_API_URL`. 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-0112d99e537f1605", "name": "Dangling fetch: GET /api/skills/${soulHash}/impact?token=${token} (frontend/script.js:9699)", "shortDescription": {"text": "Dangling fetch: GET /api/skills/${soulHash}/impact?token=${token} (frontend/script.js:9699)"}, "fullDescription": {"text": "`frontend/script.js:9699` calls `GET /api/skills/${soulHash}/impact?token=${token}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/skills/<p>/impact`\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-7a1cb37ba570a088", "name": "Dangling fetch: POST /auth/register (frontend/utils/api.js:98)", "shortDescription": {"text": "Dangling fetch: POST /auth/register (frontend/utils/api.js:98)"}, "fullDescription": {"text": "`frontend/utils/api.js:98` calls `POST /auth/register` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/auth/register`\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-5fe87d5d08b6f3b8", "name": "Dangling fetch: POST /auth/login (frontend/utils/api.js:105)", "shortDescription": {"text": "Dangling fetch: POST /auth/login (frontend/utils/api.js:105)"}, "fullDescription": {"text": "`frontend/utils/api.js:105` calls `POST /auth/login` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/auth/login`\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-e4944ff5689c1a5a", "name": "Dangling fetch: GET /auth/verify/${token} (frontend/utils/api.js:119)", "shortDescription": {"text": "Dangling fetch: GET /auth/verify/${token} (frontend/utils/api.js:119)"}, "fullDescription": {"text": "`frontend/utils/api.js:119` calls `GET /auth/verify/${token}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/auth/verify/<p>`\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-d4d80da1c130ad22", "name": "Dangling fetch: GET /auth/me (frontend/utils/api.js:123)", "shortDescription": {"text": "Dangling fetch: GET /auth/me (frontend/utils/api.js:123)"}, "fullDescription": {"text": "`frontend/utils/api.js:123` calls `GET /auth/me` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/auth/me`\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-cd5e19bae76ff4b8", "name": "Dangling fetch: PATCH /auth/me (frontend/utils/api.js:127)", "shortDescription": {"text": "Dangling fetch: PATCH /auth/me (frontend/utils/api.js:127)"}, "fullDescription": {"text": "`frontend/utils/api.js:127` calls `PATCH /auth/me` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/auth/me`\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-aee0e1c43b1108de", "name": "Dangling fetch: GET /skills/${skillId} (frontend/utils/api.js:184)", "shortDescription": {"text": "Dangling fetch: GET /skills/${skillId} (frontend/utils/api.js:184)"}, "fullDescription": {"text": "`frontend/utils/api.js:184` calls `GET /skills/${skillId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/skills/<p>`\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-5b5787c3cd646085", "name": "Dangling fetch: GET /skills/${skillId}/versions (frontend/utils/api.js:188)", "shortDescription": {"text": "Dangling fetch: GET /skills/${skillId}/versions (frontend/utils/api.js:188)"}, "fullDescription": {"text": "`frontend/utils/api.js:188` calls `GET /skills/${skillId}/versions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/skills/<p>/versions`\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-16d40b39f70f50fa", "name": "Dangling fetch: PATCH /skills/${skillId} (frontend/utils/api.js:208)", "shortDescription": {"text": "Dangling fetch: PATCH /skills/${skillId} (frontend/utils/api.js:208)"}, "fullDescription": {"text": "`frontend/utils/api.js:208` calls `PATCH /skills/${skillId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/skills/<p>`\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-9cf817fa7547129f", "name": "Dangling fetch: DELETE /skills/${skillId} (frontend/utils/api.js:215)", "shortDescription": {"text": "Dangling fetch: DELETE /skills/${skillId} (frontend/utils/api.js:215)"}, "fullDescription": {"text": "`frontend/utils/api.js:215` calls `DELETE /skills/${skillId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/skills/<p>`\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-96c7718e64a9c2a7", "name": "Dangling fetch: POST /skills/${skillId}/comments (frontend/utils/api.js:219)", "shortDescription": {"text": "Dangling fetch: POST /skills/${skillId}/comments (frontend/utils/api.js:219)"}, "fullDescription": {"text": "`frontend/utils/api.js:219` calls `POST /skills/${skillId}/comments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/skills/<p>/comments`\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-ef80b9ff1e6e1441", "name": "Dangling fetch: GET /skills/${skillId}/comments (frontend/utils/api.js:226)", "shortDescription": {"text": "Dangling fetch: GET /skills/${skillId}/comments (frontend/utils/api.js:226)"}, "fullDescription": {"text": "`frontend/utils/api.js:226` calls `GET /skills/${skillId}/comments` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/skills/<p>/comments`\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-9e0491b3dfc75e7f", "name": "Dangling fetch: GET /search?${params.toString()} (frontend/utils/api.js:246)", "shortDescription": {"text": "Dangling fetch: GET /search?${params.toString()} (frontend/utils/api.js:246)"}, "fullDescription": {"text": "`frontend/utils/api.js:246` calls `GET /search?${params.toString()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:apiCall\nNormalized path used for matching: `/search`\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-fecdf4a668994362", "name": "Unused endpoint: POST /forge/preview-from-probe", "shortDescription": {"text": "Unused endpoint: POST /forge/preview-from-probe"}, "fullDescription": {"text": "`frontend/script.js` declares `POST /forge/preview-from-probe` 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-d225a39ab02d73db", "name": "Unused endpoint: GET /playground", "shortDescription": {"text": "Unused endpoint: GET /playground"}, "fullDescription": {"text": "`backend/server.js` declares `GET /playground` 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-c57a26908b29988f", "name": "Unused endpoint: GET /archive", "shortDescription": {"text": "Unused endpoint: GET /archive"}, "fullDescription": {"text": "`backend/server.js` declares `GET /archive` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`backend/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-972b54078ec2581f", "name": "Unused endpoint: USE /api/health", "shortDescription": {"text": "Unused endpoint: USE /api/health"}, "fullDescription": {"text": "`backend/server.js` declares `USE /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-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/auth` 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-84d367763a372f89", "name": "Unused endpoint: USE /api/forge", "shortDescription": {"text": "Unused endpoint: USE /api/forge"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/forge` 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-67ce3ff14156f4ad", "name": "Unused endpoint: USE /api/skills", "shortDescription": {"text": "Unused endpoint: USE /api/skills"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/skills` 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-a74449cc5d561bad", "name": "Unused endpoint: USE /api/search", "shortDescription": {"text": "Unused endpoint: USE /api/search"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/search` 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-94ddd00dc84af41d", "name": "Unused endpoint: USE /api/email", "shortDescription": {"text": "Unused endpoint: USE /api/email"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/email` 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-49b24a943513cdf1", "name": "Unused endpoint: USE /api/download", "shortDescription": {"text": "Unused endpoint: USE /api/download"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/download` 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-5e8f238aa42558c5", "name": "Unused endpoint: USE /api/playground", "shortDescription": {"text": "Unused endpoint: USE /api/playground"}, "fullDescription": {"text": "`backend/server.js` declares `USE /api/playground` 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-337fff68588d786e", "name": "Unused endpoint: GET /admin/seed-ui", "shortDescription": {"text": "Unused endpoint: GET /admin/seed-ui"}, "fullDescription": {"text": "`backend/server.js` declares `GET /admin/seed-ui` 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-4d7f72e9b21545c1", "name": "Unused endpoint: GET /api/cors-debug", "shortDescription": {"text": "Unused endpoint: GET /api/cors-debug"}, "fullDescription": {"text": "`backend/server.js` declares `GET /api/cors-debug` 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-15cc48cf8f4f221b", "name": "Unused endpoint: GET /api/admin/diagnostics", "shortDescription": {"text": "Unused endpoint: GET /api/admin/diagnostics"}, "fullDescription": {"text": "`backend/server.js` declares `GET /api/admin/diagnostics` 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-5910b191ad2f03f5", "name": "Unused endpoint: GET /api/admin/nuke-skills-now", "shortDescription": {"text": "Unused endpoint: GET /api/admin/nuke-skills-now"}, "fullDescription": {"text": "`backend/server.js` declares `GET /api/admin/nuke-skills-now` 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-8f44b124d432e8dd", "name": "Unused endpoint: POST /api/admin/normalize-creator-names", "shortDescription": {"text": "Unused endpoint: POST /api/admin/normalize-creator-names"}, "fullDescription": {"text": "`backend/server.js` declares `POST /api/admin/normalize-creator-names` 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-bdcf845579926058", "name": "Unused endpoint: POST /api/admin/backfill-descriptions", "shortDescription": {"text": "Unused endpoint: POST /api/admin/backfill-descriptions"}, "fullDescription": {"text": "`backend/server.js` declares `POST /api/admin/backfill-descriptions` 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-59bb5c3818fbab8f", "name": "Unused endpoint: POST /send-forge-success", "shortDescription": {"text": "Unused endpoint: POST /send-forge-success"}, "fullDescription": {"text": "`backend/routes/email.js` declares `POST /send-forge-success` 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-731c57f59aaca553", "name": "Unused endpoint: POST /test", "shortDescription": {"text": "Unused endpoint: POST /test"}, "fullDescription": {"text": "`backend/routes/email.js` declares `POST /test` 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-aefeef7444df0d30", "name": "Unused endpoint: GET /certificate/:skill_id", "shortDescription": {"text": "Unused endpoint: GET /certificate/:skill_id"}, "fullDescription": {"text": "`backend/routes/email.js` declares `GET /certificate/:skill_id` 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-908ed76b8532428a", "name": "Unused endpoint: POST /send-verification", "shortDescription": {"text": "Unused endpoint: POST /send-verification"}, "fullDescription": {"text": "`backend/routes/email.js` declares `POST /send-verification` 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-b437172024d687ff", "name": "Unused endpoint: GET /diagnostics", "shortDescription": {"text": "Unused endpoint: GET /diagnostics"}, "fullDescription": {"text": "`backend/routes/email.js` declares `GET /diagnostics` 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-35dbbab88188ecf3", "name": "Unused endpoint: GET /trending", "shortDescription": {"text": "Unused endpoint: GET /trending"}, "fullDescription": {"text": "`backend/routes/search.js` declares `GET /trending` 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-c4eee4e63dc0a37b", "name": "Unused endpoint: GET /domain/:domain", "shortDescription": {"text": "Unused endpoint: GET /domain/:domain"}, "fullDescription": {"text": "`backend/routes/search.js` declares `GET /domain/:domain` 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-69cf0761271791d6", "name": "Unused endpoint: GET /:skillId", "shortDescription": {"text": "Unused endpoint: GET /:skillId"}, "fullDescription": {"text": "`backend/routes/downloads.js` declares `GET /:skillId` 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-8f95d7ec49f00406", "name": "Unused endpoint: POST /feedback", "shortDescription": {"text": "Unused endpoint: POST /feedback"}, "fullDescription": {"text": "`backend/routes/playground.js` declares `POST /feedback` 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-9fe017579824b4b4", "name": "Unused endpoint: POST /vote", "shortDescription": {"text": "Unused endpoint: POST /vote"}, "fullDescription": {"text": "`backend/routes/playground.js` declares `POST /vote` 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-8503f7261e652bae", "name": "Unused endpoint: GET /picker", "shortDescription": {"text": "Unused endpoint: GET /picker"}, "fullDescription": {"text": "`backend/routes/playground.js` declares `GET /picker` 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-86de3aa4892cb7c6", "name": "Unused endpoint: GET /stats-batch", "shortDescription": {"text": "Unused endpoint: GET /stats-batch"}, "fullDescription": {"text": "`backend/routes/playground.js` declares `GET /stats-batch` 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-66739e5a96583cb4", "name": "Unused endpoint: GET /stats/:skill_id", "shortDescription": {"text": "Unused endpoint: GET /stats/:skill_id"}, "fullDescription": {"text": "`backend/routes/playground.js` declares `GET /stats/:skill_id` 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-b258e5ea5a62d3ab", "name": "Unused endpoint: POST /forge-session", "shortDescription": {"text": "Unused endpoint: POST /forge-session"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `POST /forge-session` 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-304b6f2b403d93f7", "name": "Unused endpoint: POST /register", "shortDescription": {"text": "Unused endpoint: POST /register"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `POST /register` 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-f806d9fd8572e06d", "name": "Unused endpoint: GET /verify/:token", "shortDescription": {"text": "Unused endpoint: GET /verify/:token"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `GET /verify/:token` 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-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `POST /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-fd1dc91abf32142d", "name": "Unused endpoint: GET /me", "shortDescription": {"text": "Unused endpoint: GET /me"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `GET /me` 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-ea575b61c121b733", "name": "Unused endpoint: PATCH /me", "shortDescription": {"text": "Unused endpoint: PATCH /me"}, "fullDescription": {"text": "`backend/routes/auth.js` declares `PATCH /me` 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-de8b895bb5076eb8", "name": "Unused endpoint: POST /probe", "shortDescription": {"text": "Unused endpoint: POST /probe"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /probe` 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-892e821d1056717f", "name": "Unused endpoint: POST /preview-from-probe", "shortDescription": {"text": "Unused endpoint: POST /preview-from-probe"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /preview-from-probe` 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-970eb92d6ec2bfaa", "name": "Unused endpoint: POST /generate", "shortDescription": {"text": "Unused endpoint: POST /generate"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /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-cccfe89f81ab208f", "name": "Unused endpoint: POST /preview", "shortDescription": {"text": "Unused endpoint: POST /preview"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /preview` 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-3ecb42aee372add9", "name": "Unused endpoint: POST /save-probe-session", "shortDescription": {"text": "Unused endpoint: POST /save-probe-session"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /save-probe-session` 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-9238524d7f9ab719", "name": "Unused endpoint: POST /probe/stream", "shortDescription": {"text": "Unused endpoint: POST /probe/stream"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /probe/stream` 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-76e7b0bc9cf34275", "name": "Unused endpoint: POST /generate/stream", "shortDescription": {"text": "Unused endpoint: POST /generate/stream"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /generate/stream` 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-ac614285e2dd5669", "name": "Unused endpoint: POST /blessing", "shortDescription": {"text": "Unused endpoint: POST /blessing"}, "fullDescription": {"text": "`backend/routes/forge.js` declares `POST /blessing` 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-5970b5eab59e7a46", "name": "Unused endpoint: GET /stars/batch", "shortDescription": {"text": "Unused endpoint: GET /stars/batch"}, "fullDescription": {"text": "`backend/routes/skills.js` declares `GET /stars/batch` 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-a0b39e828499ecf0", "name": "Unused endpoint: GET /:skill_id/stats", "shortDescription": {"text": "Unused endpoint: GET /:skill_id/stats"}, "fullDescription": {"text": "`backend/routes/skills.js` declares `GET /:skill_id/stats` 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-8ab6d3692bd4051e", "name": "Unused endpoint: GET /user/skills", "shortDescription": {"text": "Unused endpoint: GET /user/skills"}, "fullDescription": {"text": "`backend/routes/skills.js` declares `GET /user/skills` 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-cc37d463febf2426", "name": "Unused endpoint: GET /:skill_id", "shortDescription": {"text": "Unused endpoint: GET /:skill_id"}, "fullDescription": {"text": "`backend/routes/skills.js` declares `GET /:skill_id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`backend/routes/skills.js` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/22999"}, "properties": {"repository": "xiaojialove-DRP/the42post", "repoUrl": "https://github.com/xiaojialove-DRP/the42post", "branch": "main"}, "results": [{"ruleId": "scanner-58cf6d46faf92b7d", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 frontend/script.js:796"}, "properties": {"repobilityId": "104e919df1ecadad", "scanner": "scanner-primary", "fingerprint": "58cf6d46faf92b7d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-1d707627c53e1cff", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/script.js:82"}, "properties": {"repobilityId": "ad5f9c38871bcbbf", "scanner": "scanner-primary", "fingerprint": "1d707627c53e1cff", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-901666a2827bb722", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/js/utils.js:35"}, "properties": {"repobilityId": "d1908a116abf2da8", "scanner": "scanner-primary", "fingerprint": "901666a2827bb722", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-726853cee13167b3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/config/cors.js:146"}, "properties": {"repobilityId": "8c0b04c5a5bbf3e4", "scanner": "scanner-primary", "fingerprint": "726853cee13167b3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fb33a461c565068b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/middleware/requestValidator.js:232"}, "properties": {"repobilityId": "98bf3d6428305f2f", "scanner": "scanner-primary", "fingerprint": "fb33a461c565068b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d466a3297c8a54ec", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/middleware/requestLogger.js:102"}, "properties": {"repobilityId": "9339cad4bbbdda07", "scanner": "scanner-primary", "fingerprint": "d466a3297c8a54ec", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5d75f4455905a66a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/migrate.js:21"}, "properties": {"repobilityId": "dc57c3c095c79cf2", "scanner": "scanner-primary", "fingerprint": "5d75f4455905a66a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7dabe078de573827", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/import-and-categorize-skills.js:20"}, "properties": {"repobilityId": "31f13096498cb607", "scanner": "scanner-primary", "fingerprint": "7dabe078de573827", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-232af540ea16498a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/seed-skills.js:135"}, "properties": {"repobilityId": "e5eff2894975862b", "scanner": "scanner-primary", "fingerprint": "232af540ea16498a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-354a3e0edfd5f98e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/seed-42-skills.js:22"}, "properties": {"repobilityId": "a57b509fffc7ddd7", "scanner": "scanner-primary", "fingerprint": "354a3e0edfd5f98e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-29dcf11950e4512a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/generate-skill-sql.js:81"}, "properties": {"repobilityId": "4bcca10f9e57d89f", "scanner": "scanner-primary", "fingerprint": "29dcf11950e4512a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9515bb5996436a07", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/backfill-descriptions.js:36"}, "properties": {"repobilityId": "7792a74e68a0fae2", "scanner": "scanner-primary", "fingerprint": "9515bb5996436a07", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cbb99566b8f4efa5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/test-connection.js:17"}, "properties": {"repobilityId": "369847bade85e479", "scanner": "scanner-primary", "fingerprint": "cbb99566b8f4efa5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3f916fc254108fa8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/creatorDigest.js:224"}, "properties": {"repobilityId": "57ad2cef9e25df17", "scanner": "scanner-primary", "fingerprint": "3f916fc254108fa8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ac4c4f334a96c0f7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/email.js:35"}, "properties": {"repobilityId": "90c0bc00fa6b82f1", "scanner": "scanner-primary", "fingerprint": "ac4c4f334a96c0f7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-58b48778b3691f87", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/logger.js:10"}, "properties": {"repobilityId": "774f0deddb47da8b", "scanner": "scanner-primary", "fingerprint": "58b48778b3691f87", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a6c0bcdf805b7ebd", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 backend/utils/llmAdapter.js:141"}, "properties": {"repobilityId": "c9d2c8fbf5b39d4d", "scanner": "scanner-primary", "fingerprint": "a6c0bcdf805b7ebd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-074b4860217dde16", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/utils/llmAdapter.js:13"}, "properties": {"repobilityId": "daabf2388b5f3ec5", "scanner": "scanner-primary", "fingerprint": "074b4860217dde16", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b22c42e019e10ad9", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 backend/routes/auth.js:223"}, "properties": {"repobilityId": "c47981c90a61d6fa", "scanner": "scanner-primary", "fingerprint": "b22c42e019e10ad9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-750de24d8346b738", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/routes/skills.js:705"}, "properties": {"repobilityId": "e9a350592b4c75c6", "scanner": "scanner-primary", "fingerprint": "750de24d8346b738", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-079e04b5b7b8d3ed", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/seed-skills-on-startup.js:18"}, "properties": {"repobilityId": "4df50efbe271bbb5", "scanner": "scanner-primary", "fingerprint": "079e04b5b7b8d3ed", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0bba9f840bbbef27", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/sqlite-adapter.js:26"}, "properties": {"repobilityId": "0c94cd3fccc80737", "scanner": "scanner-primary", "fingerprint": "0bba9f840bbbef27", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d974d39e302fc057", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/init.js:119"}, "properties": {"repobilityId": "50d7215e28652a55", "scanner": "scanner-primary", "fingerprint": "d974d39e302fc057", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f2ff6253cf97dbfc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/db/connectionPool.js:183"}, "properties": {"repobilityId": "03e37d0ebe43a188", "scanner": "scanner-primary", "fingerprint": "f2ff6253cf97dbfc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-98c523aff735f30a", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:18"}, "properties": {"repobilityId": "6b0b66db4545679f", "scanner": "scanner-primary", "fingerprint": "98c523aff735f30a", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 2}}}]}, {"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-9710c8d059e53154", "level": "none", "message": {"text": "No frontend routes/components detected"}, "properties": {"repobilityId": "44ca61485762e494", "scanner": "scanner-primary", "fingerprint": "9710c8d059e53154", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-206348a820cc5272", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/script.js:518"}, "properties": {"repobilityId": "f3b960afbfe85f64", "scanner": "scanner-primary", "fingerprint": "206348a820cc5272", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/script.js"}, "region": {"startLine": 518}}}]}, {"ruleId": "scanner-22be419e59a8418e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in frontend/playground.html:1683"}, "properties": {"repobilityId": "9af899faf232d8c7", "scanner": "scanner-primary", "fingerprint": "22be419e59a8418e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/playground.html"}, "region": {"startLine": 1683}}}]}, {"ruleId": "scanner-0cdf74336728c563", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in backend/server.js:286"}, "properties": {"repobilityId": "5d3986a3e5e3aab0", "scanner": "scanner-primary", "fingerprint": "0cdf74336728c563", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/server.js"}, "region": {"startLine": 286}}}]}, {"ruleId": "scanner-6ec2740dae57a5d8", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in backend/server.js:131"}, "properties": {"repobilityId": "c509a14561e07714", "scanner": "scanner-primary", "fingerprint": "6ec2740dae57a5d8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/server.js"}, "region": {"startLine": 131}}}]}, {"ruleId": "scanner-9c87ea3179110852", "level": "error", "message": {"text": "Insecure pattern 'new_function_used' in backend/scripts/seed-skills.js:162"}, "properties": {"repobilityId": "4f44401c57e41e6c", "scanner": "scanner-primary", "fingerprint": "9c87ea3179110852", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "new_function_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed-skills.js"}, "region": {"startLine": 162}}}]}, {"ruleId": "scanner-78ec093b8cab7de0", "level": "error", "message": {"text": "Insecure pattern 'new_function_used' in backend/scripts/seed-42-skills.js:130"}, "properties": {"repobilityId": "d822cbb0589e1422", "scanner": "scanner-primary", "fingerprint": "78ec093b8cab7de0", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "new_function_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed-42-skills.js"}, "region": {"startLine": 130}}}]}, {"ruleId": "scanner-e475ff7002659934", "level": "error", "message": {"text": "Insecure pattern 'new_function_used' in backend/scripts/generate-skill-sql.js:38"}, "properties": {"repobilityId": "67975598128e1fde", "scanner": "scanner-primary", "fingerprint": "e475ff7002659934", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "new_function_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/generate-skill-sql.js"}, "region": {"startLine": 38}}}]}, {"ruleId": "scanner-9e316d1e4e1e4d33", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in backend/db/sqlite-adapter.js:141"}, "properties": {"repobilityId": "b145b22c09abfbb5", "scanner": "scanner-primary", "fingerprint": "9e316d1e4e1e4d33", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/db/sqlite-adapter.js"}, "region": {"startLine": 141}}}]}, {"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-887963f389585700", "level": "note", "message": {"text": "Very large file: frontend/script.js (9940 lines)"}, "properties": {"repobilityId": "da6685e99a1875be", "scanner": "scanner-primary", "fingerprint": "887963f389585700", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-67287529926a71ac", "level": "note", "message": {"text": "Very large file: backend/utils/skillGeneration.js (1000 lines)"}, "properties": {"repobilityId": "c7e70f2172ede095", "scanner": "scanner-primary", "fingerprint": "67287529926a71ac", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-3a092b5c39e242a1", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: backend/package.json"}, "properties": {"repobilityId": "fc853e57ce7048c4", "scanner": "scanner-primary", "fingerprint": "3a092b5c39e242a1", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "1010c887bc394942", "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": "0a4dd00dda2bc8ee", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "57e86a65544c8479", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "23e6d1d67819b79d", "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": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "b5153c1b5a3eb6f6", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "9a8bd9419c65210a", "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": "06cc20873660e19a", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea339e794b710506", "level": "note", "message": {"text": "Legacy-named symbol `preview_prompt_copy` in frontend/script.js:1088"}, "properties": {"repobilityId": "f4a368e1221fbb0d", "scanner": "scanner-primary", "fingerprint": "ea339e794b710506", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-4e6dc7b28ec40c6e", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/script.js:1598"}, "properties": {"repobilityId": "8feb4f538d1e9546", "scanner": "scanner-primary", "fingerprint": "4e6dc7b28ec40c6e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-10b61c939fa53081", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/script.js:404"}, "properties": {"repobilityId": "fcb55974ba6ec9bb", "scanner": "scanner-primary", "fingerprint": "10b61c939fa53081", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-96f75b5a2c826e68", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/server.js:345"}, "properties": {"repobilityId": "15e28bede92c8f95", "scanner": "scanner-primary", "fingerprint": "96f75b5a2c826e68", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-36017d13bab87f4e", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/utils/auth.js:77"}, "properties": {"repobilityId": "a4ca6b52c3bab5a9", "scanner": "scanner-primary", "fingerprint": "36017d13bab87f4e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cfee5d47fb16a78b", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/utils/skillGeneration.js:234"}, "properties": {"repobilityId": "49ad44a41374947a", "scanner": "scanner-primary", "fingerprint": "cfee5d47fb16a78b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c79aa1c5f0a5aff9", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/utils/backupScheduler.js:58"}, "properties": {"repobilityId": "de94b238eeb9c084", "scanner": "scanner-primary", "fingerprint": "c79aa1c5f0a5aff9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b5cdbe69011ed29d", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/routes/playground.js:29"}, "properties": {"repobilityId": "84e2dcf781a1c71d", "scanner": "scanner-primary", "fingerprint": "b5cdbe69011ed29d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4d309ccc3c843bae", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/routes/auth.js:27"}, "properties": {"repobilityId": "beb461a700fc05af", "scanner": "scanner-primary", "fingerprint": "4d309ccc3c843bae", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-51070dad27d4e743", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/routes/forge.js:93"}, "properties": {"repobilityId": "b10bf778fa998747", "scanner": "scanner-primary", "fingerprint": "51070dad27d4e743", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b474b34392433652", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/routes/skills.js:23"}, "properties": {"repobilityId": "e04f07af7ea43847", "scanner": "scanner-primary", "fingerprint": "b474b34392433652", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-05d8fe721848e118", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/db/sqlite-adapter.js:68"}, "properties": {"repobilityId": "3ebc65c1cec88bf9", "scanner": "scanner-primary", "fingerprint": "05d8fe721848e118", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e2b2a7e79a37666c", "level": "note", "message": {"text": "Legacy-named symbol `probe_logs_old` in backend/db/init.js:120"}, "properties": {"repobilityId": "6a9a592969125e07", "scanner": "scanner-primary", "fingerprint": "e2b2a7e79a37666c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-0c60cbe717a726da", "level": "none", "message": {"text": "Commented-code block (8 lines) in backend/db/init.js:9"}, "properties": {"repobilityId": "c225100118a1ba01", "scanner": "scanner-primary", "fingerprint": "0c60cbe717a726da", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d0b17c8c07a7421d", "level": "note", "message": {"text": "8 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "17fe720e8247f9df", "scanner": "scanner-primary", "fingerprint": "d0b17c8c07a7421d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-0112d99e537f1605", "level": "error", "message": {"text": "Dangling fetch: GET /api/skills/${soulHash}/impact?token=${token} (frontend/script.js:9699)"}, "properties": {"repobilityId": "a713e0e977ba6098", "scanner": "scanner-primary", "fingerprint": "0112d99e537f1605", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7a1cb37ba570a088", "level": "error", "message": {"text": "Dangling fetch: POST /auth/register (frontend/utils/api.js:98)"}, "properties": {"repobilityId": "116397345a8009c4", "scanner": "scanner-primary", "fingerprint": "7a1cb37ba570a088", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-5fe87d5d08b6f3b8", "level": "error", "message": {"text": "Dangling fetch: POST /auth/login (frontend/utils/api.js:105)"}, "properties": {"repobilityId": "8fc730bf7d994570", "scanner": "scanner-primary", "fingerprint": "5fe87d5d08b6f3b8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-e4944ff5689c1a5a", "level": "error", "message": {"text": "Dangling fetch: GET /auth/verify/${token} (frontend/utils/api.js:119)"}, "properties": {"repobilityId": "43432a0e46ba51ce", "scanner": "scanner-primary", "fingerprint": "e4944ff5689c1a5a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-d4d80da1c130ad22", "level": "error", "message": {"text": "Dangling fetch: GET /auth/me (frontend/utils/api.js:123)"}, "properties": {"repobilityId": "273ea739910d2078", "scanner": "scanner-primary", "fingerprint": "d4d80da1c130ad22", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-cd5e19bae76ff4b8", "level": "error", "message": {"text": "Dangling fetch: PATCH /auth/me (frontend/utils/api.js:127)"}, "properties": {"repobilityId": "23069834f20855c0", "scanner": "scanner-primary", "fingerprint": "cd5e19bae76ff4b8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-aee0e1c43b1108de", "level": "error", "message": {"text": "Dangling fetch: GET /skills/${skillId} (frontend/utils/api.js:184)"}, "properties": {"repobilityId": "f57e66d51ba8c71f", "scanner": "scanner-primary", "fingerprint": "aee0e1c43b1108de", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-5b5787c3cd646085", "level": "error", "message": {"text": "Dangling fetch: GET /skills/${skillId}/versions (frontend/utils/api.js:188)"}, "properties": {"repobilityId": "2d23a08c4613219b", "scanner": "scanner-primary", "fingerprint": "5b5787c3cd646085", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-16d40b39f70f50fa", "level": "error", "message": {"text": "Dangling fetch: PATCH /skills/${skillId} (frontend/utils/api.js:208)"}, "properties": {"repobilityId": "c55a8fc4c4c2e6f1", "scanner": "scanner-primary", "fingerprint": "16d40b39f70f50fa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-9cf817fa7547129f", "level": "error", "message": {"text": "Dangling fetch: DELETE /skills/${skillId} (frontend/utils/api.js:215)"}, "properties": {"repobilityId": "2397b5774c61e856", "scanner": "scanner-primary", "fingerprint": "9cf817fa7547129f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-96c7718e64a9c2a7", "level": "error", "message": {"text": "Dangling fetch: POST /skills/${skillId}/comments (frontend/utils/api.js:219)"}, "properties": {"repobilityId": "149bf683ce9ea191", "scanner": "scanner-primary", "fingerprint": "96c7718e64a9c2a7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-ef80b9ff1e6e1441", "level": "error", "message": {"text": "Dangling fetch: GET /skills/${skillId}/comments (frontend/utils/api.js:226)"}, "properties": {"repobilityId": "4abc49069aa4f036", "scanner": "scanner-primary", "fingerprint": "ef80b9ff1e6e1441", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-9e0491b3dfc75e7f", "level": "error", "message": {"text": "Dangling fetch: GET /search?${params.toString()} (frontend/utils/api.js:246)"}, "properties": {"repobilityId": "e29a6ce8ec85e366", "scanner": "scanner-primary", "fingerprint": "9e0491b3dfc75e7f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:apiCall"]}}, {"ruleId": "scanner-fecdf4a668994362", "level": "note", "message": {"text": "Unused endpoint: POST /forge/preview-from-probe"}, "properties": {"repobilityId": "2375fe1d12960493", "scanner": "scanner-primary", "fingerprint": "fecdf4a668994362", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d225a39ab02d73db", "level": "note", "message": {"text": "Unused endpoint: GET /playground"}, "properties": {"repobilityId": "407806ec0641386b", "scanner": "scanner-primary", "fingerprint": "d225a39ab02d73db", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c57a26908b29988f", "level": "note", "message": {"text": "Unused endpoint: GET /archive"}, "properties": {"repobilityId": "c11c94b959763d56", "scanner": "scanner-primary", "fingerprint": "c57a26908b29988f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "7d4772f7c52bce64", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-972b54078ec2581f", "level": "note", "message": {"text": "Unused endpoint: USE /api/health"}, "properties": {"repobilityId": "376cfcfbc7d04d4b", "scanner": "scanner-primary", "fingerprint": "972b54078ec2581f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eb452fbfb454d20", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth"}, "properties": {"repobilityId": "0a5793afc5ea0a13", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-84d367763a372f89", "level": "note", "message": {"text": "Unused endpoint: USE /api/forge"}, "properties": {"repobilityId": "e1c981c9fa76b61f", "scanner": "scanner-primary", "fingerprint": "84d367763a372f89", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-67ce3ff14156f4ad", "level": "note", "message": {"text": "Unused endpoint: USE /api/skills"}, "properties": {"repobilityId": "587dc44c6b0e20b7", "scanner": "scanner-primary", "fingerprint": "67ce3ff14156f4ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a74449cc5d561bad", "level": "note", "message": {"text": "Unused endpoint: USE /api/search"}, "properties": {"repobilityId": "863bfe1cbf2d8543", "scanner": "scanner-primary", "fingerprint": "a74449cc5d561bad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-94ddd00dc84af41d", "level": "note", "message": {"text": "Unused endpoint: USE /api/email"}, "properties": {"repobilityId": "ecc372b7c6ac795a", "scanner": "scanner-primary", "fingerprint": "94ddd00dc84af41d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-49b24a943513cdf1", "level": "note", "message": {"text": "Unused endpoint: USE /api/download"}, "properties": {"repobilityId": "aaf8291caedf7045", "scanner": "scanner-primary", "fingerprint": "49b24a943513cdf1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5e8f238aa42558c5", "level": "note", "message": {"text": "Unused endpoint: USE /api/playground"}, "properties": {"repobilityId": "8313877e0f2255c6", "scanner": "scanner-primary", "fingerprint": "5e8f238aa42558c5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-337fff68588d786e", "level": "note", "message": {"text": "Unused endpoint: GET /admin/seed-ui"}, "properties": {"repobilityId": "3318c46c3f623c96", "scanner": "scanner-primary", "fingerprint": "337fff68588d786e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d7f72e9b21545c1", "level": "note", "message": {"text": "Unused endpoint: GET /api/cors-debug"}, "properties": {"repobilityId": "a179838442426bae", "scanner": "scanner-primary", "fingerprint": "4d7f72e9b21545c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-15cc48cf8f4f221b", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/diagnostics"}, "properties": {"repobilityId": "754a22495fb7b89a", "scanner": "scanner-primary", "fingerprint": "15cc48cf8f4f221b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5910b191ad2f03f5", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/nuke-skills-now"}, "properties": {"repobilityId": "93c9ba81c404f29f", "scanner": "scanner-primary", "fingerprint": "5910b191ad2f03f5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8f44b124d432e8dd", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/normalize-creator-names"}, "properties": {"repobilityId": "a55ca9bc17c2e716", "scanner": "scanner-primary", "fingerprint": "8f44b124d432e8dd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bdcf845579926058", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/backfill-descriptions"}, "properties": {"repobilityId": "9b2af8d679c02f40", "scanner": "scanner-primary", "fingerprint": "bdcf845579926058", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-59bb5c3818fbab8f", "level": "note", "message": {"text": "Unused endpoint: POST /send-forge-success"}, "properties": {"repobilityId": "af82f77ea3abe483", "scanner": "scanner-primary", "fingerprint": "59bb5c3818fbab8f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-731c57f59aaca553", "level": "note", "message": {"text": "Unused endpoint: POST /test"}, "properties": {"repobilityId": "96fcc7f8ced870a2", "scanner": "scanner-primary", "fingerprint": "731c57f59aaca553", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-aefeef7444df0d30", "level": "note", "message": {"text": "Unused endpoint: GET /certificate/:skill_id"}, "properties": {"repobilityId": "c0fe4e392649b619", "scanner": "scanner-primary", "fingerprint": "aefeef7444df0d30", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-908ed76b8532428a", "level": "note", "message": {"text": "Unused endpoint: POST /send-verification"}, "properties": {"repobilityId": "87bfcff7c4b86401", "scanner": "scanner-primary", "fingerprint": "908ed76b8532428a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b437172024d687ff", "level": "note", "message": {"text": "Unused endpoint: GET /diagnostics"}, "properties": {"repobilityId": "58fdf2b431765860", "scanner": "scanner-primary", "fingerprint": "b437172024d687ff", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-35dbbab88188ecf3", "level": "note", "message": {"text": "Unused endpoint: GET /trending"}, "properties": {"repobilityId": "c0be31022442f3f1", "scanner": "scanner-primary", "fingerprint": "35dbbab88188ecf3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c4eee4e63dc0a37b", "level": "note", "message": {"text": "Unused endpoint: GET /domain/:domain"}, "properties": {"repobilityId": "f32dffd84038aadc", "scanner": "scanner-primary", "fingerprint": "c4eee4e63dc0a37b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-69cf0761271791d6", "level": "note", "message": {"text": "Unused endpoint: GET /:skillId"}, "properties": {"repobilityId": "bc451c808372e580", "scanner": "scanner-primary", "fingerprint": "69cf0761271791d6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8f95d7ec49f00406", "level": "note", "message": {"text": "Unused endpoint: POST /feedback"}, "properties": {"repobilityId": "c8545a04f4f0cb65", "scanner": "scanner-primary", "fingerprint": "8f95d7ec49f00406", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9fe017579824b4b4", "level": "note", "message": {"text": "Unused endpoint: POST /vote"}, "properties": {"repobilityId": "0b90693e36ad36b8", "scanner": "scanner-primary", "fingerprint": "9fe017579824b4b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8503f7261e652bae", "level": "note", "message": {"text": "Unused endpoint: GET /picker"}, "properties": {"repobilityId": "74ba68c74fd30979", "scanner": "scanner-primary", "fingerprint": "8503f7261e652bae", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-86de3aa4892cb7c6", "level": "note", "message": {"text": "Unused endpoint: GET /stats-batch"}, "properties": {"repobilityId": "13b70afcd9b9a02e", "scanner": "scanner-primary", "fingerprint": "86de3aa4892cb7c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-66739e5a96583cb4", "level": "note", "message": {"text": "Unused endpoint: GET /stats/:skill_id"}, "properties": {"repobilityId": "46439f8426ad5bbe", "scanner": "scanner-primary", "fingerprint": "66739e5a96583cb4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b258e5ea5a62d3ab", "level": "note", "message": {"text": "Unused endpoint: POST /forge-session"}, "properties": {"repobilityId": "3803b6092d5c981b", "scanner": "scanner-primary", "fingerprint": "b258e5ea5a62d3ab", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-304b6f2b403d93f7", "level": "note", "message": {"text": "Unused endpoint: POST /register"}, "properties": {"repobilityId": "75111c8cb20116c6", "scanner": "scanner-primary", "fingerprint": "304b6f2b403d93f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f806d9fd8572e06d", "level": "note", "message": {"text": "Unused endpoint: GET /verify/:token"}, "properties": {"repobilityId": "1f2dc5472a56c147", "scanner": "scanner-primary", "fingerprint": "f806d9fd8572e06d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "0739200902492336", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "e4a6fbd9b6ee5f8b", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ea575b61c121b733", "level": "note", "message": {"text": "Unused endpoint: PATCH /me"}, "properties": {"repobilityId": "c9b734daaba33471", "scanner": "scanner-primary", "fingerprint": "ea575b61c121b733", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-de8b895bb5076eb8", "level": "note", "message": {"text": "Unused endpoint: POST /probe"}, "properties": {"repobilityId": "7e1311da4c43c598", "scanner": "scanner-primary", "fingerprint": "de8b895bb5076eb8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-892e821d1056717f", "level": "note", "message": {"text": "Unused endpoint: POST /preview-from-probe"}, "properties": {"repobilityId": "e20f6bb181a3b2cb", "scanner": "scanner-primary", "fingerprint": "892e821d1056717f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-970eb92d6ec2bfaa", "level": "note", "message": {"text": "Unused endpoint: POST /generate"}, "properties": {"repobilityId": "6a400f11e5891e08", "scanner": "scanner-primary", "fingerprint": "970eb92d6ec2bfaa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cccfe89f81ab208f", "level": "note", "message": {"text": "Unused endpoint: POST /preview"}, "properties": {"repobilityId": "1655b394cb3b8b89", "scanner": "scanner-primary", "fingerprint": "cccfe89f81ab208f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3ecb42aee372add9", "level": "note", "message": {"text": "Unused endpoint: POST /save-probe-session"}, "properties": {"repobilityId": "7a8019031600f4de", "scanner": "scanner-primary", "fingerprint": "3ecb42aee372add9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9238524d7f9ab719", "level": "note", "message": {"text": "Unused endpoint: POST /probe/stream"}, "properties": {"repobilityId": "d101a0b1531dd7d5", "scanner": "scanner-primary", "fingerprint": "9238524d7f9ab719", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76e7b0bc9cf34275", "level": "note", "message": {"text": "Unused endpoint: POST /generate/stream"}, "properties": {"repobilityId": "39fe8711dfa18abd", "scanner": "scanner-primary", "fingerprint": "76e7b0bc9cf34275", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac614285e2dd5669", "level": "note", "message": {"text": "Unused endpoint: POST /blessing"}, "properties": {"repobilityId": "68885277e94c421b", "scanner": "scanner-primary", "fingerprint": "ac614285e2dd5669", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5970b5eab59e7a46", "level": "note", "message": {"text": "Unused endpoint: GET /stars/batch"}, "properties": {"repobilityId": "957e3d06def3f5e1", "scanner": "scanner-primary", "fingerprint": "5970b5eab59e7a46", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a0b39e828499ecf0", "level": "note", "message": {"text": "Unused endpoint: GET /:skill_id/stats"}, "properties": {"repobilityId": "a4a18f8c63eb4d69", "scanner": "scanner-primary", "fingerprint": "a0b39e828499ecf0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8ab6d3692bd4051e", "level": "note", "message": {"text": "Unused endpoint: GET /user/skills"}, "properties": {"repobilityId": "c516fb12e2442263", "scanner": "scanner-primary", "fingerprint": "8ab6d3692bd4051e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cc37d463febf2426", "level": "note", "message": {"text": "Unused endpoint: GET /:skill_id"}, "properties": {"repobilityId": "143a60860448b65a", "scanner": "scanner-primary", "fingerprint": "cc37d463febf2426", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "0c52b1571dacc21c", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}