{"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-20dece4f6c590456", "name": "Stray `console.log` in TS/JS \u2014 vite.config.js:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 vite.config.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-ea3ff7445d6526c6", "name": "Stray `console.log` in TS/JS \u2014 sync.js:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 sync.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-10cfda82b073be22", "name": "Stray `console.log` in TS/JS \u2014 api/quotes.js:277", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 api/quotes.js:277"}, "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-04ed470e10daf974", "name": "Stray `console.log` in TS/JS \u2014 api/ingest-wheel-earnings.js:139", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest-wheel-earnings.js:139"}, "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-62343df0c1ab2703", "name": "Stray `console.log` in TS/JS \u2014 api/ingest-iv.js:109", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest-iv.js:109"}, "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-9eb451f84c65d215", "name": "Stray `console.log` in TS/JS \u2014 api/ingest-s5fi.js:63", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest-s5fi.js:63"}, "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-669a5eaf7540c045", "name": "Stray `console.log` in TS/JS \u2014 api/ingest.js:67", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest.js:67"}, "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-d42bdf041d7fb2af", "name": "Stray `console.log` in TS/JS \u2014 api/_lib/notify.js:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 api/_lib/notify.js:71"}, "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-1168ec4b27f298eb", "name": "Stray `console.log` in TS/JS \u2014 scripts/calibrate_forecast.js:226", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/calibrate_forecast.js:226"}, "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-a24a0d7d0590e030", "name": "Icon-only button without accessible name \u2014 src/redesign/components/explore/RadarSurface.jsx:521", "shortDescription": {"text": "Icon-only button without accessible name \u2014 src/redesign/components/explore/RadarSurface.jsx:521"}, "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-a0c441cb9d585447", "name": "Insecure pattern 'node_child_process' in vite.config.js:3", "shortDescription": {"text": "Insecure pattern 'node_child_process' in vite.config.js:3"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e825ce6c3e929b2c", "name": "Insecure pattern 'direct_innerhtml_assignment' in architecture.html:375", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in architecture.html:375"}, "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-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-371b94554f9610c5", "name": "Very large file: src/components/OpenPositionsTab.jsx (1379 lines)", "shortDescription": {"text": "Very large file: src/components/OpenPositionsTab.jsx (1379 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-a723c2aa280ba876", "name": "Very large file: src/components/RadarTab.jsx (1593 lines)", "shortDescription": {"text": "Very large file: src/components/RadarTab.jsx (1593 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": "32 tests / 183 src (ratio 0.17)."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 22 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 32 placeholder/mock markers across 16 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: license, ci, operator-readme. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci, operator-readme. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bea357a6497a2d5d", "name": "Agent authority lacks a verifier contract: CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2c5f98b152cddb6d", "name": "Agent authority lacks a verifier contract: .claude/launch.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-941b5aad8422022a", "name": "Commented-code block (7 lines) in middleware.js:3", "shortDescription": {"text": "Commented-code block (7 lines) in middleware.js:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4a537a382d71e2fd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 middleware.js:9", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 middleware.js:9"}, "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-c1d0ac80f875f012", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/macro.js:329", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/macro.js:329"}, "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-87d2fa9ec86d1d32", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/radar-sample.js:74", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/radar-sample.js:74"}, "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-b15f6a98d01afd09", "name": "Commented-code block (8 lines) in api/quotes.js:161", "shortDescription": {"text": "Commented-code block (8 lines) in api/quotes.js:161"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f500b9b8d7783664", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/quotes.js:52", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/quotes.js:52"}, "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-4b81c1c25f8882b6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/eod-snapshot.js:43", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/eod-snapshot.js:43"}, "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-83aca60da9b4e27d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/earnings-chain.js:57", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/earnings-chain.js:57"}, "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-43834c834b832805", "name": "Commented-code block (5 lines) in api/sync.js:200", "shortDescription": {"text": "Commented-code block (5 lines) in api/sync.js:200"}, "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-830af1352a765e36", "name": "Commented-code block (5 lines) in api/bb.js:59", "shortDescription": {"text": "Commented-code block (5 lines) in api/bb.js:59"}, "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-5df43668da32cf97", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/bb.js:36", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/bb.js:36"}, "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-e007df7871280534", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/intraday-snapshot.js:45", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/intraday-snapshot.js:45"}, "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-0b846d7dcf06ecb0", "name": "Commented-code block (5 lines) in api/monthly-review.js:235", "shortDescription": {"text": "Commented-code block (5 lines) in api/monthly-review.js:235"}, "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-039c242c1c8bbb2f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/roll-analysis.js:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/roll-analysis.js:54"}, "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-b44aa4870ff570fe", "name": "Legacy-named symbol `forecast_v2` in api/snapshot.js:385", "shortDescription": {"text": "Legacy-named symbol `forecast_v2` in api/snapshot.js:385"}, "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-3e28f4aab277da76", "name": "Commented-code block (5 lines) in api/snapshot.js:125", "shortDescription": {"text": "Commented-code block (5 lines) in api/snapshot.js:125"}, "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-1fd1edd0a1bf8567", "name": "Commented-code block (5 lines) in api/ingest.js:77", "shortDescription": {"text": "Commented-code block (5 lines) in api/ingest.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-d77be59966dda775", "name": "Commented-code block (5 lines) in api/_lib/computeAssignedShareIncome.js:63", "shortDescription": {"text": "Commented-code block (5 lines) in api/_lib/computeAssignedShareIncome.js:63"}, "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-a6bcab80fc988328", "name": "Commented-code block (5 lines) in api/_lib/lifespan.js:110", "shortDescription": {"text": "Commented-code block (5 lines) in api/_lib/lifespan.js:110"}, "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-90708774e74d897a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/_lib/notify.js:34", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/_lib/notify.js:34"}, "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-89d44f2b76677493", "name": "`fetch()` without try/.catch or AbortSignal \u2014 api/_lib/publicCom.js:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/_lib/publicCom.js:32"}, "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-efaeabcde24020c3", "name": "Commented-code block (6 lines) in api/_lib/cohortHistory.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in api/_lib/cohortHistory.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4820fd37219ef306", "name": "Commented-code block (12 lines) in api/_lib/__tests__/decision-framing.test.js:192", "shortDescription": {"text": "Commented-code block (12 lines) in api/_lib/__tests__/decision-framing.test.js:192"}, "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-73ae9b749bac42ea", "name": "Commented-code block (8 lines) in api/_lib/__tests__/lifespan-cut-redeploy.test.js:80", "shortDescription": {"text": "Commented-code block (8 lines) in api/_lib/__tests__/lifespan-cut-redeploy.test.js:80"}, "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-48109de3e9005ab2", "name": "Commented-code block (11 lines) in lib/syncSheets.js:97", "shortDescription": {"text": "Commented-code block (11 lines) in lib/syncSheets.js:97"}, "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-1fc8768edd505615", "name": "Commented-code block (7 lines) in lib/parseSheets.js:174", "shortDescription": {"text": "Commented-code block (7 lines) in lib/parseSheets.js:174"}, "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-1808be1fdb1d099c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/parseSheets.js:293", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/parseSheets.js:293"}, "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-201f5b595989549e", "name": "Commented-code block (5 lines) in src/config/__tests__/aiBaskets.test.js:4", "shortDescription": {"text": "Commented-code block (5 lines) in src/config/__tests__/aiBaskets.test.js:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2d64a584727f8186", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SyncButton.jsx:23", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SyncButton.jsx:23"}, "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-1044c35ec4a91113", "name": "Commented-code block (5 lines) in src/components/PersistentHeader.jsx:65", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/PersistentHeader.jsx:65"}, "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-ce907058878b6b6a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/CohortsPanel.jsx:230", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/CohortsPanel.jsx:230"}, "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-1d91f38f91908de6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/journal/JournalTab.jsx:169", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/journal/JournalTab.jsx:169"}, "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-88876dff9b070ebc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/journal/JournalQuickAdd.jsx:282", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/journal/JournalQuickAdd.jsx:282"}, "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-d4d88dc14cbd2648", "name": "Commented-code block (7 lines) in src/lib/cohorts.js:39", "shortDescription": {"text": "Commented-code block (7 lines) in src/lib/cohorts.js:39"}, "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-a81995380538b7c9", "name": "Commented-code block (5 lines) in src/lib/focusEngine.js:6", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/focusEngine.js:6"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c9d21316b3ce772e", "name": "Commented-code block (6 lines) in src/lib/journalApi.js:1", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/journalApi.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6c8311919337d93d", "name": "Commented-code block (8 lines) in src/lib/earningsEngine.js:299", "shortDescription": {"text": "Commented-code block (8 lines) in src/lib/earningsEngine.js:299"}, "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-93754ee99e0a4c96", "name": "Commented-code block (5 lines) in src/lib/holdYield.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/holdYield.js:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c42ee9b958bec117", "name": "Commented-code block (6 lines) in src/lib/pipelineForecast.js:14", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/pipelineForecast.js:14"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2851e7568bc34984", "name": "Commented-code block (5 lines) in src/lib/strategyBasket.js:9", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/strategyBasket.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-e38a4fcd8a99156d", "name": "Commented-code block (6 lines) in src/lib/tags.js:69", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/tags.js:69"}, "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-2a38360f618ef9bc", "name": "Commented-code block (8 lines) in src/lib/__tests__/pipelineForecast.test.js:305", "shortDescription": {"text": "Commented-code block (8 lines) in src/lib/__tests__/pipelineForecast.test.js:305"}, "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-05be3db69efa0bd2", "name": "Commented-code block (5 lines) in src/lib/__tests__/earningsEngine.test.js:110", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/__tests__/earningsEngine.test.js:110"}, "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-3aa568571886dd95", "name": "Commented-code block (7 lines) in src/hooks/useRadarSamples.js:3", "shortDescription": {"text": "Commented-code block (7 lines) in src/hooks/useRadarSamples.js:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ec3aebb3fc73a3b5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useRadarSamples.js:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useRadarSamples.js:37"}, "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-5d40a49b4591f49b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useRollAnalysis.js:89", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useRollAnalysis.js:89"}, "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-1d3234848fd9bb92", "name": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d (api/eod-snapshot.", "shortDescription": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d (api/eod-snapshot.js:43)"}, "fullDescription": {"text": "`api/eod-snapshot.js:43` calls `GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/query1.finance.yahoo.com/v8/finance/chart/<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-4ba0db307c8c3196", "name": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d (api/sync.js:57)", "shortDescription": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d (api/sync.js:57)"}, "fullDescription": {"text": "`api/sync.js:57` calls `GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/query1.finance.yahoo.com/v8/finance/chart/%5evix`\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-50c54179560b104a", "name": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d (api/intraday-snap", "shortDescription": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d (api/intraday-snapshot.js:45)"}, "fullDescription": {"text": "`api/intraday-snapshot.js:45` calls `GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/query1.finance.yahoo.com/v8/finance/chart/<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-ac7410423f044a8c", "name": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d (api/vix.js:17)", "shortDescription": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d (api/vix.js:17)"}, "fullDescription": {"text": "`api/vix.js:17` calls `GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/query1.finance.yahoo.com/v8/finance/chart/%5evix`\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-f3593846f9418195", "name": "Dangling fetch: DELETE /api/delete-trade?id=${encodeURIComponent(trade.id)} (src/App.jsx:56)", "shortDescription": {"text": "Dangling fetch: DELETE /api/delete-trade?id=${encodeURIComponent(trade.id)} (src/App.jsx:56)"}, "fullDescription": {"text": "`src/App.jsx:56` calls `DELETE /api/delete-trade?id=${encodeURIComponent(trade.id)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/delete-trade`\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-9624b48a3205b70d", "name": "Dangling fetch: GET /api/data (src/App.jsx:65)", "shortDescription": {"text": "Dangling fetch: GET /api/data (src/App.jsx:65)"}, "fullDescription": {"text": "`src/App.jsx:65` calls `GET /api/data` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/data`\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-4df152c45b80835f", "name": "Dangling fetch: POST /api/sync (src/components/SyncButton.jsx:18)", "shortDescription": {"text": "Dangling fetch: POST /api/sync (src/components/SyncButton.jsx:18)"}, "fullDescription": {"text": "`src/components/SyncButton.jsx:18` calls `POST /api/sync` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/sync`\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-6b79c7b079021306", "name": "Dangling fetch: GET /api/data?t=${Date.now()} (src/components/SyncButton.jsx:23)", "shortDescription": {"text": "Dangling fetch: GET /api/data?t=${Date.now()} (src/components/SyncButton.jsx:23)"}, "fullDescription": {"text": "`src/components/SyncButton.jsx:23` calls `GET /api/data?t=${Date.now()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/data`\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-4a187f45788c4b0d", "name": "Dangling fetch: POST /api/sync (src/components/SyncButton.jsx:35)", "shortDescription": {"text": "Dangling fetch: POST /api/sync (src/components/SyncButton.jsx:35)"}, "fullDescription": {"text": "`src/components/SyncButton.jsx:35` calls `POST /api/sync` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/sync`\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-47da678415f2e221", "name": "Dangling fetch: GET /api/position-lifespan (src/components/TickersTab.jsx:139)", "shortDescription": {"text": "Dangling fetch: GET /api/position-lifespan (src/components/TickersTab.jsx:139)"}, "fullDescription": {"text": "`src/components/TickersTab.jsx:139` calls `GET /api/position-lifespan` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/position-lifespan`\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-352787cc7e42c922", "name": "Dangling fetch: POST /api/journal-entry (src/components/OpenPositionsTab.jsx:991)", "shortDescription": {"text": "Dangling fetch: POST /api/journal-entry (src/components/OpenPositionsTab.jsx:991)"}, "fullDescription": {"text": "`src/components/OpenPositionsTab.jsx:991` calls `POST /api/journal-entry` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/journal-entry`\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-4758b8464312d2e7", "name": "Dangling fetch: GET /api/position-history?${qs} (src/components/PositionHistoryPanel.jsx:23)", "shortDescription": {"text": "Dangling fetch: GET /api/position-history?${qs} (src/components/PositionHistoryPanel.jsx:23)"}, "fullDescription": {"text": "`src/components/PositionHistoryPanel.jsx:23` calls `GET /api/position-history?${qs}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/position-history`\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-8662a382ce506ed3", "name": "Dangling fetch: GET /api/macro-ai (src/components/MacroTab.jsx:60)", "shortDescription": {"text": "Dangling fetch: GET /api/macro-ai (src/components/MacroTab.jsx:60)"}, "fullDescription": {"text": "`src/components/MacroTab.jsx:60` calls `GET /api/macro-ai` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/macro-ai`\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-6e2d667b5a69654b", "name": "Dangling fetch: GET /api/earnings-dates (src/components/EarningsTab.jsx:45)", "shortDescription": {"text": "Dangling fetch: GET /api/earnings-dates (src/components/EarningsTab.jsx:45)"}, "fullDescription": {"text": "`src/components/EarningsTab.jsx:45` calls `GET /api/earnings-dates` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/earnings-dates`\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-a7de00461b309c2a", "name": "Dangling fetch: GET /api/earnings-chain?ticker=${ticker}&expiry=${e} (src/components/EarningsTab.jsx:77)", "shortDescription": {"text": "Dangling fetch: GET /api/earnings-chain?ticker=${ticker}&expiry=${e} (src/components/EarningsTab.jsx:77)"}, "fullDescription": {"text": "`src/components/EarningsTab.jsx:77` calls `GET /api/earnings-chain?ticker=${ticker}&expiry=${e}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/earnings-chain`\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-0f780ee2c081730f", "name": "Dangling fetch: GET /api/focus-context (src/components/RadarTab.jsx:1318)", "shortDescription": {"text": "Dangling fetch: GET /api/focus-context (src/components/RadarTab.jsx:1318)"}, "fullDescription": {"text": "`src/components/RadarTab.jsx:1318` calls `GET /api/focus-context` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/focus-context`\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-e7b26142c163c00e", "name": "Dangling fetch: GET /api/cohort-history?tag=${encodeURIComponent(tag)} (src/components/CohortsPanel.jsx:53)", "shortDescription": {"text": "Dangling fetch: GET /api/cohort-history?tag=${encodeURIComponent(tag)} (src/components/CohortsPanel.jsx:53)"}, "fullDescription": {"text": "`src/components/CohortsPanel.jsx:53` calls `GET /api/cohort-history?tag=${encodeURIComponent(tag)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/cohort-history`\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-851f13379920229a", "name": "Dangling fetch: DELETE /api/journal-entry?id=${encodeURIComponent(e.id)} (src/components/CohortsPanel.jsx:230)", "shortDescription": {"text": "Dangling fetch: DELETE /api/journal-entry?id=${encodeURIComponent(e.id)} (src/components/CohortsPanel.jsx:230)"}, "fullDescription": {"text": "`src/components/CohortsPanel.jsx:230` calls `DELETE /api/journal-entry?id=${encodeURIComponent(e.id)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/journal-entry`\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-94d457b23f593e73", "name": "Dangling fetch: PATCH /api/journal-entry (src/components/CohortsPanel.jsx:235)", "shortDescription": {"text": "Dangling fetch: PATCH /api/journal-entry (src/components/CohortsPanel.jsx:235)"}, "fullDescription": {"text": "`src/components/CohortsPanel.jsx:235` calls `PATCH /api/journal-entry` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/journal-entry`\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-a648f2590c1e8878", "name": "Dangling fetch: POST /api/radar-preset (src/components/radar/RadarPresetBar.jsx:61)", "shortDescription": {"text": "Dangling fetch: POST /api/radar-preset (src/components/radar/RadarPresetBar.jsx:61)"}, "fullDescription": {"text": "`src/components/radar/RadarPresetBar.jsx:61` calls `POST /api/radar-preset` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/radar-preset`\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-e6115e72f69886fd", "name": "Dangling fetch: PATCH /api/radar-preset (src/components/radar/RadarPresetBar.jsx:128)", "shortDescription": {"text": "Dangling fetch: PATCH /api/radar-preset (src/components/radar/RadarPresetBar.jsx:128)"}, "fullDescription": {"text": "`src/components/radar/RadarPresetBar.jsx:128` calls `PATCH /api/radar-preset` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/radar-preset`\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-bdf3153f04e08ac0", "name": "Dangling fetch: DELETE /api/radar-preset?id=${encodeURIComponent(preset.id)} (src/components/radar/RadarPresetBar.jsx:13", "shortDescription": {"text": "Dangling fetch: DELETE /api/radar-preset?id=${encodeURIComponent(preset.id)} (src/components/radar/RadarPresetBar.jsx:139)"}, "fullDescription": {"text": "`src/components/radar/RadarPresetBar.jsx:139` calls `DELETE /api/radar-preset?id=${encodeURIComponent(preset.id)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/radar-preset`\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-10eb57b48755abad", "name": "Dangling fetch: PATCH /api/journal-entry (src/components/journal/JournalTab.jsx:169)", "shortDescription": {"text": "Dangling fetch: PATCH /api/journal-entry (src/components/journal/JournalTab.jsx:169)"}, "fullDescription": {"text": "`src/components/journal/JournalTab.jsx:169` calls `PATCH /api/journal-entry` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/journal-entry`\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-b2e6d2769ddd2bf6", "name": "Dangling fetch: DELETE /api/journal-entry?id=${encodeURIComponent(id)} (src/components/journal/JournalTab.jsx:191)", "shortDescription": {"text": "Dangling fetch: DELETE /api/journal-entry?id=${encodeURIComponent(id)} (src/components/journal/JournalTab.jsx:191)"}, "fullDescription": {"text": "`src/components/journal/JournalTab.jsx:191` calls `DELETE /api/journal-entry?id=${encodeURIComponent(id)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/journal-entry`\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-4ac30fd5bdaf7d4e", "name": "Dangling fetch: POST /api/journal-entry (src/components/journal/JournalQuickAdd.jsx:282)", "shortDescription": {"text": "Dangling fetch: POST /api/journal-entry (src/components/journal/JournalQuickAdd.jsx:282)"}, "fullDescription": {"text": "`src/components/journal/JournalQuickAdd.jsx:282` calls `POST /api/journal-entry` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/journal-entry`\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-911535b7b4862d02", "name": "Dangling fetch: GET /api/... (src/lib/auth.js:3)", "shortDescription": {"text": "Dangling fetch: GET /api/... (src/lib/auth.js:3)"}, "fullDescription": {"text": "`src/lib/auth.js:3` calls `GET /api/...` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/...`\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-012cb1d6a55f371d", "name": "Dangling fetch: GET /api/data (src/redesign/App.jsx:63)", "shortDescription": {"text": "Dangling fetch: GET /api/data (src/redesign/App.jsx:63)"}, "fullDescription": {"text": "`src/redesign/App.jsx:63` calls `GET /api/data` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/data`\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-e9367a291b08af4e", "name": "Dangling fetch: GET /api/macro (src/redesign/components/focus/FocusCommandCenter.jsx:18)", "shortDescription": {"text": "Dangling fetch: GET /api/macro (src/redesign/components/focus/FocusCommandCenter.jsx:18)"}, "fullDescription": {"text": "`src/redesign/components/focus/FocusCommandCenter.jsx:18` calls `GET /api/macro` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/macro`\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-02ce36f682d1760a", "name": "Dangling fetch: GET /api/earnings-dates (src/redesign/components/explore/EarningsSurface.jsx:45)", "shortDescription": {"text": "Dangling fetch: GET /api/earnings-dates (src/redesign/components/explore/EarningsSurface.jsx:45)"}, "fullDescription": {"text": "`src/redesign/components/explore/EarningsSurface.jsx:45` calls `GET /api/earnings-dates` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/earnings-dates`\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-1c1c28d7a66244f1", "name": "Dangling fetch: GET /api/earnings-chain?ticker=${ticker}&expiry=${e} (src/redesign/components/explore/EarningsSurface.js", "shortDescription": {"text": "Dangling fetch: GET /api/earnings-chain?ticker=${ticker}&expiry=${e} (src/redesign/components/explore/EarningsSurface.jsx:79)"}, "fullDescription": {"text": "`src/redesign/components/explore/EarningsSurface.jsx:79` calls `GET /api/earnings-chain?ticker=${ticker}&expiry=${e}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/earnings-chain`\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-5b451656d9895b4e", "name": "Dangling fetch: GET /api/assigned-share-income (src/hooks/useAssignedShareIncome.js:26)", "shortDescription": {"text": "Dangling fetch: GET /api/assigned-share-income (src/hooks/useAssignedShareIncome.js:26)"}, "fullDescription": {"text": "`src/hooks/useAssignedShareIncome.js:26` calls `GET /api/assigned-share-income` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/assigned-share-income`\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-dec4c8154a0ca25f", "name": "Dangling fetch: GET /api/macro (src/hooks/useMacro.js:14)", "shortDescription": {"text": "Dangling fetch: GET /api/macro (src/hooks/useMacro.js:14)"}, "fullDescription": {"text": "`src/hooks/useMacro.js:14` calls `GET /api/macro` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/macro`\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-41b68891c5a66135", "name": "Dangling fetch: GET /api/bb (src/hooks/useRadar.js:11)", "shortDescription": {"text": "Dangling fetch: GET /api/bb (src/hooks/useRadar.js:11)"}, "fullDescription": {"text": "`src/hooks/useRadar.js:11` calls `GET /api/bb` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bb`\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-4df3a64316f9b90b", "name": "Dangling fetch: GET /api/quotes (src/hooks/useQuotes.js:33)", "shortDescription": {"text": "Dangling fetch: GET /api/quotes (src/hooks/useQuotes.js:33)"}, "fullDescription": {"text": "`src/hooks/useQuotes.js:33` calls `GET /api/quotes` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/quotes`\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-1dcca49765b8a689", "name": "Dangling fetch: GET /api/radar-sample?tickers=${encodeURIComponent(key)} (src/hooks/useRadarSamples.js:37)", "shortDescription": {"text": "Dangling fetch: GET /api/radar-sample?tickers=${encodeURIComponent(key)} (src/hooks/useRadarSamples.js:37)"}, "fullDescription": {"text": "`src/hooks/useRadarSamples.js:37` calls `GET /api/radar-sample?tickers=${encodeURIComponent(key)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/radar-sample`\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-46bb226acfda9b16", "name": "Dangling fetch: GET /api/ticker-detail?ticker=${encodeURIComponent(ticker)} (src/hooks/useTickerDetail.js:20)", "shortDescription": {"text": "Dangling fetch: GET /api/ticker-detail?ticker=${encodeURIComponent(ticker)} (src/hooks/useTickerDetail.js:20)"}, "fullDescription": {"text": "`src/hooks/useTickerDetail.js:20` calls `GET /api/ticker-detail?ticker=${encodeURIComponent(ticker)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/ticker-detail`\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-be110fd7fd3a1e8b", "name": "Dangling fetch: POST /api/roll-analysis?threshold=${threshold} (src/hooks/useRollAnalysis.js:66)", "shortDescription": {"text": "Dangling fetch: POST /api/roll-analysis?threshold=${threshold} (src/hooks/useRollAnalysis.js:66)"}, "fullDescription": {"text": "`src/hooks/useRollAnalysis.js:66` calls `POST /api/roll-analysis?threshold=${threshold}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/roll-analysis`\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-e2b6a86554f32a55", "name": "Dangling fetch: GET /api/roll-analysis (src/hooks/useRollAnalysis.js:89)", "shortDescription": {"text": "Dangling fetch: GET /api/roll-analysis (src/hooks/useRollAnalysis.js:89)"}, "fullDescription": {"text": "`src/hooks/useRollAnalysis.js:89` calls `GET /api/roll-analysis` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/roll-analysis`\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-3a749fedd2096e18", "name": "Dangling fetch: GET /api/vix (src/hooks/useLiveVix.js:13)", "shortDescription": {"text": "Dangling fetch: GET /api/vix (src/hooks/useLiveVix.js:13)"}, "fullDescription": {"text": "`src/hooks/useLiveVix.js:13` calls `GET /api/vix` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/vix`\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-ae8d8599f6e24375", "name": "Dangling fetch: GET /api/focus-context (src/hooks/useFocusItems.js:31)", "shortDescription": {"text": "Dangling fetch: GET /api/focus-context (src/hooks/useFocusItems.js:31)"}, "fullDescription": {"text": "`src/hooks/useFocusItems.js:31` calls `GET /api/focus-context` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/focus-context`\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-dc3560ef7ccc2dc6", "name": "Unused endpoint: USE /api/sync", "shortDescription": {"text": "Unused endpoint: USE /api/sync"}, "fullDescription": {"text": "`vite.config.js` declares `USE /api/sync` 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-171501667618361a", "name": "Unused endpoint: USE /api/data", "shortDescription": {"text": "Unused endpoint: USE /api/data"}, "fullDescription": {"text": "`vite.config.js` declares `USE /api/data` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/22276"}, "properties": {"repository": "vinh-jones/trading-dashboard", "repoUrl": "https://github.com/vinh-jones/trading-dashboard", "branch": "main"}, "results": [{"ruleId": "scanner-20dece4f6c590456", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 vite.config.js:36"}, "properties": {"repobilityId": "71d9ca087513828f", "scanner": "scanner-primary", "fingerprint": "20dece4f6c590456", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ea3ff7445d6526c6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 sync.js:26"}, "properties": {"repobilityId": "cd2696692aa8a554", "scanner": "scanner-primary", "fingerprint": "ea3ff7445d6526c6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-10cfda82b073be22", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 api/quotes.js:277"}, "properties": {"repobilityId": "98cda5e3e1fa9b40", "scanner": "scanner-primary", "fingerprint": "10cfda82b073be22", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-04ed470e10daf974", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest-wheel-earnings.js:139"}, "properties": {"repobilityId": "47fad60e7ce422e2", "scanner": "scanner-primary", "fingerprint": "04ed470e10daf974", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-62343df0c1ab2703", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest-iv.js:109"}, "properties": {"repobilityId": "cfcbcd7e11c1901e", "scanner": "scanner-primary", "fingerprint": "62343df0c1ab2703", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9eb451f84c65d215", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest-s5fi.js:63"}, "properties": {"repobilityId": "eb5c2f722ef69a6a", "scanner": "scanner-primary", "fingerprint": "9eb451f84c65d215", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-669a5eaf7540c045", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 api/ingest.js:67"}, "properties": {"repobilityId": "e90f302d047a4e67", "scanner": "scanner-primary", "fingerprint": "669a5eaf7540c045", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d42bdf041d7fb2af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 api/_lib/notify.js:71"}, "properties": {"repobilityId": "d418a4ab7746b243", "scanner": "scanner-primary", "fingerprint": "d42bdf041d7fb2af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1168ec4b27f298eb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/calibrate_forecast.js:226"}, "properties": {"repobilityId": "4ee46b19000ba6e3", "scanner": "scanner-primary", "fingerprint": "1168ec4b27f298eb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a24a0d7d0590e030", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 src/redesign/components/explore/RadarSurface.jsx:521"}, "properties": {"repobilityId": "dda8852cb6aab8d5", "scanner": "scanner-primary", "fingerprint": "a24a0d7d0590e030", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-a0c441cb9d585447", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in vite.config.js:3"}, "properties": {"repobilityId": "fb99635354426984", "scanner": "scanner-primary", "fingerprint": "a0c441cb9d585447", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "vite.config.js"}, "region": {"startLine": 3}}}]}, {"ruleId": "scanner-e825ce6c3e929b2c", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in architecture.html:375"}, "properties": {"repobilityId": "4e6c87d444e47c62", "scanner": "scanner-primary", "fingerprint": "e825ce6c3e929b2c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "architecture.html"}, "region": {"startLine": 375}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-371b94554f9610c5", "level": "note", "message": {"text": "Very large file: src/components/OpenPositionsTab.jsx (1379 lines)"}, "properties": {"repobilityId": "43c2b2c703407978", "scanner": "scanner-primary", "fingerprint": "371b94554f9610c5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-a723c2aa280ba876", "level": "note", "message": {"text": "Very large file: src/components/RadarTab.jsx (1593 lines)"}, "properties": {"repobilityId": "d127ddd8207e62c7", "scanner": "scanner-primary", "fingerprint": "a723c2aa280ba876", "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-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "66db85becb435084", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "bf17e4defb26247a", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "aa660c5901f53ef2", "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": "aeed3f0446e13383", "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": "595aa7543823a7b3", "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": "e0d39d0b2a0805ae", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "764a1d273f9304d8", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "0771674e5c9588d1", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "b72f0959eeaec9e5", "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": "7665b6ba6e82872f", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-bea357a6497a2d5d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "properties": {"repobilityId": "aae72df3934829ac", "scanner": "scanner-primary", "fingerprint": "bea357a6497a2d5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2c5f98b152cddb6d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "properties": {"repobilityId": "0de48c0f4ab303d8", "scanner": "scanner-primary", "fingerprint": "2c5f98b152cddb6d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/launch.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-941b5aad8422022a", "level": "none", "message": {"text": "Commented-code block (7 lines) in middleware.js:3"}, "properties": {"repobilityId": "767be17037fbccc5", "scanner": "scanner-primary", "fingerprint": "941b5aad8422022a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4a537a382d71e2fd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 middleware.js:9"}, "properties": {"repobilityId": "e50876c647422fc2", "scanner": "scanner-primary", "fingerprint": "4a537a382d71e2fd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c1d0ac80f875f012", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/macro.js:329"}, "properties": {"repobilityId": "5645cb72267d8f8c", "scanner": "scanner-primary", "fingerprint": "c1d0ac80f875f012", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-87d2fa9ec86d1d32", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/radar-sample.js:74"}, "properties": {"repobilityId": "fcb5f01b14b02ca7", "scanner": "scanner-primary", "fingerprint": "87d2fa9ec86d1d32", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b15f6a98d01afd09", "level": "none", "message": {"text": "Commented-code block (8 lines) in api/quotes.js:161"}, "properties": {"repobilityId": "0257acdfbea4cd47", "scanner": "scanner-primary", "fingerprint": "b15f6a98d01afd09", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f500b9b8d7783664", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/quotes.js:52"}, "properties": {"repobilityId": "b868df275a46777d", "scanner": "scanner-primary", "fingerprint": "f500b9b8d7783664", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4b81c1c25f8882b6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/eod-snapshot.js:43"}, "properties": {"repobilityId": "7f33583239ccc4b9", "scanner": "scanner-primary", "fingerprint": "4b81c1c25f8882b6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-83aca60da9b4e27d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/earnings-chain.js:57"}, "properties": {"repobilityId": "3e6ba1c61604d4d3", "scanner": "scanner-primary", "fingerprint": "83aca60da9b4e27d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-43834c834b832805", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/sync.js:200"}, "properties": {"repobilityId": "64d30aa5ecb3fc6f", "scanner": "scanner-primary", "fingerprint": "43834c834b832805", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-830af1352a765e36", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/bb.js:59"}, "properties": {"repobilityId": "266b5ce98d9789f0", "scanner": "scanner-primary", "fingerprint": "830af1352a765e36", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5df43668da32cf97", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/bb.js:36"}, "properties": {"repobilityId": "4cd17b25bd80b0f4", "scanner": "scanner-primary", "fingerprint": "5df43668da32cf97", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e007df7871280534", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/intraday-snapshot.js:45"}, "properties": {"repobilityId": "de8bf0aa7f6f380b", "scanner": "scanner-primary", "fingerprint": "e007df7871280534", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0b846d7dcf06ecb0", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/monthly-review.js:235"}, "properties": {"repobilityId": "49fabbc0009d12ff", "scanner": "scanner-primary", "fingerprint": "0b846d7dcf06ecb0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-039c242c1c8bbb2f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/roll-analysis.js:54"}, "properties": {"repobilityId": "49bc26cf35c31feb", "scanner": "scanner-primary", "fingerprint": "039c242c1c8bbb2f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b44aa4870ff570fe", "level": "note", "message": {"text": "Legacy-named symbol `forecast_v2` in api/snapshot.js:385"}, "properties": {"repobilityId": "f3a3043487735c4f", "scanner": "scanner-primary", "fingerprint": "b44aa4870ff570fe", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-3e28f4aab277da76", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/snapshot.js:125"}, "properties": {"repobilityId": "01fda4be3787945f", "scanner": "scanner-primary", "fingerprint": "3e28f4aab277da76", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1fd1edd0a1bf8567", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/ingest.js:77"}, "properties": {"repobilityId": "adb9f82a8c5eb4cc", "scanner": "scanner-primary", "fingerprint": "1fd1edd0a1bf8567", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d77be59966dda775", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/_lib/computeAssignedShareIncome.js:63"}, "properties": {"repobilityId": "c8ce9524e79b74a8", "scanner": "scanner-primary", "fingerprint": "d77be59966dda775", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a6bcab80fc988328", "level": "none", "message": {"text": "Commented-code block (5 lines) in api/_lib/lifespan.js:110"}, "properties": {"repobilityId": "eb37fd0712a6f5d6", "scanner": "scanner-primary", "fingerprint": "a6bcab80fc988328", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-90708774e74d897a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/_lib/notify.js:34"}, "properties": {"repobilityId": "ac9c082d88787dc1", "scanner": "scanner-primary", "fingerprint": "90708774e74d897a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-89d44f2b76677493", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 api/_lib/publicCom.js:32"}, "properties": {"repobilityId": "9b888f508cdb2f6a", "scanner": "scanner-primary", "fingerprint": "89d44f2b76677493", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-efaeabcde24020c3", "level": "none", "message": {"text": "Commented-code block (6 lines) in api/_lib/cohortHistory.js:1"}, "properties": {"repobilityId": "3c8f4a5efeae7bf0", "scanner": "scanner-primary", "fingerprint": "efaeabcde24020c3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4820fd37219ef306", "level": "none", "message": {"text": "Commented-code block (12 lines) in api/_lib/__tests__/decision-framing.test.js:192"}, "properties": {"repobilityId": "29feb7ce342960bd", "scanner": "scanner-primary", "fingerprint": "4820fd37219ef306", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-73ae9b749bac42ea", "level": "none", "message": {"text": "Commented-code block (8 lines) in api/_lib/__tests__/lifespan-cut-redeploy.test.js:80"}, "properties": {"repobilityId": "71f2999c09b75abf", "scanner": "scanner-primary", "fingerprint": "73ae9b749bac42ea", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-48109de3e9005ab2", "level": "none", "message": {"text": "Commented-code block (11 lines) in lib/syncSheets.js:97"}, "properties": {"repobilityId": "d7cb1c01efe146df", "scanner": "scanner-primary", "fingerprint": "48109de3e9005ab2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1fc8768edd505615", "level": "none", "message": {"text": "Commented-code block (7 lines) in lib/parseSheets.js:174"}, "properties": {"repobilityId": "b65971cb8fb5c5a4", "scanner": "scanner-primary", "fingerprint": "1fc8768edd505615", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1808be1fdb1d099c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/parseSheets.js:293"}, "properties": {"repobilityId": "036ad28d2e34f56d", "scanner": "scanner-primary", "fingerprint": "1808be1fdb1d099c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-201f5b595989549e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/config/__tests__/aiBaskets.test.js:4"}, "properties": {"repobilityId": "ede9726aa4aa84c0", "scanner": "scanner-primary", "fingerprint": "201f5b595989549e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2d64a584727f8186", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/SyncButton.jsx:23"}, "properties": {"repobilityId": "9f04957445171cf9", "scanner": "scanner-primary", "fingerprint": "2d64a584727f8186", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1044c35ec4a91113", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/PersistentHeader.jsx:65"}, "properties": {"repobilityId": "fd026ea66f1779c3", "scanner": "scanner-primary", "fingerprint": "1044c35ec4a91113", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ce907058878b6b6a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/CohortsPanel.jsx:230"}, "properties": {"repobilityId": "c219aec4234141f0", "scanner": "scanner-primary", "fingerprint": "ce907058878b6b6a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1d91f38f91908de6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/journal/JournalTab.jsx:169"}, "properties": {"repobilityId": "40abe5a18d0e88e0", "scanner": "scanner-primary", "fingerprint": "1d91f38f91908de6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-88876dff9b070ebc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/journal/JournalQuickAdd.jsx:282"}, "properties": {"repobilityId": "4373c975a8d46f51", "scanner": "scanner-primary", "fingerprint": "88876dff9b070ebc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d4d88dc14cbd2648", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/lib/cohorts.js:39"}, "properties": {"repobilityId": "57e19f0ce6673c7a", "scanner": "scanner-primary", "fingerprint": "d4d88dc14cbd2648", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a81995380538b7c9", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/focusEngine.js:6"}, "properties": {"repobilityId": "ee33cdf352d96fee", "scanner": "scanner-primary", "fingerprint": "a81995380538b7c9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c9d21316b3ce772e", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/journalApi.js:1"}, "properties": {"repobilityId": "1cdd18bb4e6ead16", "scanner": "scanner-primary", "fingerprint": "c9d21316b3ce772e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6c8311919337d93d", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/lib/earningsEngine.js:299"}, "properties": {"repobilityId": "21e6ad95c11a8150", "scanner": "scanner-primary", "fingerprint": "6c8311919337d93d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-93754ee99e0a4c96", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/holdYield.js:1"}, "properties": {"repobilityId": "8341fc353946c1ae", "scanner": "scanner-primary", "fingerprint": "93754ee99e0a4c96", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c42ee9b958bec117", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/pipelineForecast.js:14"}, "properties": {"repobilityId": "af0af031aa12b0dd", "scanner": "scanner-primary", "fingerprint": "c42ee9b958bec117", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2851e7568bc34984", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/strategyBasket.js:9"}, "properties": {"repobilityId": "6f8792e7c30c0160", "scanner": "scanner-primary", "fingerprint": "2851e7568bc34984", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e38a4fcd8a99156d", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/tags.js:69"}, "properties": {"repobilityId": "ea7f19a3df5005a6", "scanner": "scanner-primary", "fingerprint": "e38a4fcd8a99156d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2a38360f618ef9bc", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/lib/__tests__/pipelineForecast.test.js:305"}, "properties": {"repobilityId": "49e9e029e5c8ab9e", "scanner": "scanner-primary", "fingerprint": "2a38360f618ef9bc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-05be3db69efa0bd2", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/__tests__/earningsEngine.test.js:110"}, "properties": {"repobilityId": "1fb15dd00444df31", "scanner": "scanner-primary", "fingerprint": "05be3db69efa0bd2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3aa568571886dd95", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/hooks/useRadarSamples.js:3"}, "properties": {"repobilityId": "1486577c3046e623", "scanner": "scanner-primary", "fingerprint": "3aa568571886dd95", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ec3aebb3fc73a3b5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useRadarSamples.js:37"}, "properties": {"repobilityId": "bb801c52cd66a7d6", "scanner": "scanner-primary", "fingerprint": "ec3aebb3fc73a3b5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5d40a49b4591f49b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/hooks/useRollAnalysis.js:89"}, "properties": {"repobilityId": "460b88512acaf7bb", "scanner": "scanner-primary", "fingerprint": "5d40a49b4591f49b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1d3234848fd9bb92", "level": "error", "message": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d (api/eod-snapshot.js:43)"}, "properties": {"repobilityId": "2d78d9040855592e", "scanner": "scanner-primary", "fingerprint": "1d3234848fd9bb92", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4ba0db307c8c3196", "level": "error", "message": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d (api/sync.js:57)"}, "properties": {"repobilityId": "c9a7f8f7cfbdee1b", "scanner": "scanner-primary", "fingerprint": "4ba0db307c8c3196", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-50c54179560b104a", "level": "error", "message": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/${encoded}?interval=1d&range=1d (api/intraday-snapshot.js:45)"}, "properties": {"repobilityId": "12b1826ab318441f", "scanner": "scanner-primary", "fingerprint": "50c54179560b104a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ac7410423f044a8c", "level": "error", "message": {"text": "Dangling fetch: GET https://query1.finance.yahoo.com/v8/finance/chart/%5EVIX?interval=1d&range=1d (api/vix.js:17)"}, "properties": {"repobilityId": "7f2e3b9e4047bb79", "scanner": "scanner-primary", "fingerprint": "ac7410423f044a8c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f3593846f9418195", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/delete-trade?id=${encodeURIComponent(trade.id)} (src/App.jsx:56)"}, "properties": {"repobilityId": "02d284a47ea6d4d5", "scanner": "scanner-primary", "fingerprint": "f3593846f9418195", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9624b48a3205b70d", "level": "error", "message": {"text": "Dangling fetch: GET /api/data (src/App.jsx:65)"}, "properties": {"repobilityId": "25b299f109c35bbd", "scanner": "scanner-primary", "fingerprint": "9624b48a3205b70d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4df152c45b80835f", "level": "error", "message": {"text": "Dangling fetch: POST /api/sync (src/components/SyncButton.jsx:18)"}, "properties": {"repobilityId": "b7eb4b25c3f1f102", "scanner": "scanner-primary", "fingerprint": "4df152c45b80835f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6b79c7b079021306", "level": "error", "message": {"text": "Dangling fetch: GET /api/data?t=${Date.now()} (src/components/SyncButton.jsx:23)"}, "properties": {"repobilityId": "24333163208bea70", "scanner": "scanner-primary", "fingerprint": "6b79c7b079021306", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4a187f45788c4b0d", "level": "error", "message": {"text": "Dangling fetch: POST /api/sync (src/components/SyncButton.jsx:35)"}, "properties": {"repobilityId": "b45b17008cb9370f", "scanner": "scanner-primary", "fingerprint": "4a187f45788c4b0d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-47da678415f2e221", "level": "error", "message": {"text": "Dangling fetch: GET /api/position-lifespan (src/components/TickersTab.jsx:139)"}, "properties": {"repobilityId": "f9f1f0e43e2d62be", "scanner": "scanner-primary", "fingerprint": "47da678415f2e221", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-352787cc7e42c922", "level": "error", "message": {"text": "Dangling fetch: POST /api/journal-entry (src/components/OpenPositionsTab.jsx:991)"}, "properties": {"repobilityId": "0b91363e2353275d", "scanner": "scanner-primary", "fingerprint": "352787cc7e42c922", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4758b8464312d2e7", "level": "error", "message": {"text": "Dangling fetch: GET /api/position-history?${qs} (src/components/PositionHistoryPanel.jsx:23)"}, "properties": {"repobilityId": "9412873532c5ad28", "scanner": "scanner-primary", "fingerprint": "4758b8464312d2e7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8662a382ce506ed3", "level": "error", "message": {"text": "Dangling fetch: GET /api/macro-ai (src/components/MacroTab.jsx:60)"}, "properties": {"repobilityId": "112669bbc17d20a7", "scanner": "scanner-primary", "fingerprint": "8662a382ce506ed3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6e2d667b5a69654b", "level": "error", "message": {"text": "Dangling fetch: GET /api/earnings-dates (src/components/EarningsTab.jsx:45)"}, "properties": {"repobilityId": "a72b17f831b35d23", "scanner": "scanner-primary", "fingerprint": "6e2d667b5a69654b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a7de00461b309c2a", "level": "error", "message": {"text": "Dangling fetch: GET /api/earnings-chain?ticker=${ticker}&expiry=${e} (src/components/EarningsTab.jsx:77)"}, "properties": {"repobilityId": "036c988709eb32d0", "scanner": "scanner-primary", "fingerprint": "a7de00461b309c2a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0f780ee2c081730f", "level": "error", "message": {"text": "Dangling fetch: GET /api/focus-context (src/components/RadarTab.jsx:1318)"}, "properties": {"repobilityId": "d7d39694050c9d06", "scanner": "scanner-primary", "fingerprint": "0f780ee2c081730f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e7b26142c163c00e", "level": "error", "message": {"text": "Dangling fetch: GET /api/cohort-history?tag=${encodeURIComponent(tag)} (src/components/CohortsPanel.jsx:53)"}, "properties": {"repobilityId": "b815f77d967c10b5", "scanner": "scanner-primary", "fingerprint": "e7b26142c163c00e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-851f13379920229a", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/journal-entry?id=${encodeURIComponent(e.id)} (src/components/CohortsPanel.jsx:230)"}, "properties": {"repobilityId": "9c6fbfd65ad86a2b", "scanner": "scanner-primary", "fingerprint": "851f13379920229a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-94d457b23f593e73", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/journal-entry (src/components/CohortsPanel.jsx:235)"}, "properties": {"repobilityId": "758b99a0a012ad18", "scanner": "scanner-primary", "fingerprint": "94d457b23f593e73", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a648f2590c1e8878", "level": "error", "message": {"text": "Dangling fetch: POST /api/radar-preset (src/components/radar/RadarPresetBar.jsx:61)"}, "properties": {"repobilityId": "06f191a3dc5340e1", "scanner": "scanner-primary", "fingerprint": "a648f2590c1e8878", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e6115e72f69886fd", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/radar-preset (src/components/radar/RadarPresetBar.jsx:128)"}, "properties": {"repobilityId": "0fd9217d49237038", "scanner": "scanner-primary", "fingerprint": "e6115e72f69886fd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-bdf3153f04e08ac0", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/radar-preset?id=${encodeURIComponent(preset.id)} (src/components/radar/RadarPresetBar.jsx:139)"}, "properties": {"repobilityId": "4e14dc57fbe99854", "scanner": "scanner-primary", "fingerprint": "bdf3153f04e08ac0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-10eb57b48755abad", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/journal-entry (src/components/journal/JournalTab.jsx:169)"}, "properties": {"repobilityId": "31fe61d6f34c3177", "scanner": "scanner-primary", "fingerprint": "10eb57b48755abad", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b2e6d2769ddd2bf6", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/journal-entry?id=${encodeURIComponent(id)} (src/components/journal/JournalTab.jsx:191)"}, "properties": {"repobilityId": "cdde237fc51e8f33", "scanner": "scanner-primary", "fingerprint": "b2e6d2769ddd2bf6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4ac30fd5bdaf7d4e", "level": "error", "message": {"text": "Dangling fetch: POST /api/journal-entry (src/components/journal/JournalQuickAdd.jsx:282)"}, "properties": {"repobilityId": "38c233f95fef3b2e", "scanner": "scanner-primary", "fingerprint": "4ac30fd5bdaf7d4e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-911535b7b4862d02", "level": "error", "message": {"text": "Dangling fetch: GET /api/... (src/lib/auth.js:3)"}, "properties": {"repobilityId": "1103c0db4798030d", "scanner": "scanner-primary", "fingerprint": "911535b7b4862d02", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-012cb1d6a55f371d", "level": "error", "message": {"text": "Dangling fetch: GET /api/data (src/redesign/App.jsx:63)"}, "properties": {"repobilityId": "7a39698f7b5e389e", "scanner": "scanner-primary", "fingerprint": "012cb1d6a55f371d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e9367a291b08af4e", "level": "error", "message": {"text": "Dangling fetch: GET /api/macro (src/redesign/components/focus/FocusCommandCenter.jsx:18)"}, "properties": {"repobilityId": "1ff8678b66e0e38e", "scanner": "scanner-primary", "fingerprint": "e9367a291b08af4e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-02ce36f682d1760a", "level": "error", "message": {"text": "Dangling fetch: GET /api/earnings-dates (src/redesign/components/explore/EarningsSurface.jsx:45)"}, "properties": {"repobilityId": "0b86eba1d21642c2", "scanner": "scanner-primary", "fingerprint": "02ce36f682d1760a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1c1c28d7a66244f1", "level": "error", "message": {"text": "Dangling fetch: GET /api/earnings-chain?ticker=${ticker}&expiry=${e} (src/redesign/components/explore/EarningsSurface.jsx:79)"}, "properties": {"repobilityId": "ae511652170feecd", "scanner": "scanner-primary", "fingerprint": "1c1c28d7a66244f1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5b451656d9895b4e", "level": "error", "message": {"text": "Dangling fetch: GET /api/assigned-share-income (src/hooks/useAssignedShareIncome.js:26)"}, "properties": {"repobilityId": "7f7e87172acdb38e", "scanner": "scanner-primary", "fingerprint": "5b451656d9895b4e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dec4c8154a0ca25f", "level": "error", "message": {"text": "Dangling fetch: GET /api/macro (src/hooks/useMacro.js:14)"}, "properties": {"repobilityId": "7216941bc31a8b0d", "scanner": "scanner-primary", "fingerprint": "dec4c8154a0ca25f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-41b68891c5a66135", "level": "error", "message": {"text": "Dangling fetch: GET /api/bb (src/hooks/useRadar.js:11)"}, "properties": {"repobilityId": "c38dde6d8442cbb8", "scanner": "scanner-primary", "fingerprint": "41b68891c5a66135", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4df3a64316f9b90b", "level": "error", "message": {"text": "Dangling fetch: GET /api/quotes (src/hooks/useQuotes.js:33)"}, "properties": {"repobilityId": "92c23130a3bf1427", "scanner": "scanner-primary", "fingerprint": "4df3a64316f9b90b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1dcca49765b8a689", "level": "error", "message": {"text": "Dangling fetch: GET /api/radar-sample?tickers=${encodeURIComponent(key)} (src/hooks/useRadarSamples.js:37)"}, "properties": {"repobilityId": "671cf5128360213e", "scanner": "scanner-primary", "fingerprint": "1dcca49765b8a689", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-46bb226acfda9b16", "level": "error", "message": {"text": "Dangling fetch: GET /api/ticker-detail?ticker=${encodeURIComponent(ticker)} (src/hooks/useTickerDetail.js:20)"}, "properties": {"repobilityId": "d732f4b18cc08800", "scanner": "scanner-primary", "fingerprint": "46bb226acfda9b16", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-be110fd7fd3a1e8b", "level": "error", "message": {"text": "Dangling fetch: POST /api/roll-analysis?threshold=${threshold} (src/hooks/useRollAnalysis.js:66)"}, "properties": {"repobilityId": "41e067d2bfb9d72c", "scanner": "scanner-primary", "fingerprint": "be110fd7fd3a1e8b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e2b6a86554f32a55", "level": "error", "message": {"text": "Dangling fetch: GET /api/roll-analysis (src/hooks/useRollAnalysis.js:89)"}, "properties": {"repobilityId": "80528a15a30bff06", "scanner": "scanner-primary", "fingerprint": "e2b6a86554f32a55", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3a749fedd2096e18", "level": "error", "message": {"text": "Dangling fetch: GET /api/vix (src/hooks/useLiveVix.js:13)"}, "properties": {"repobilityId": "0583d955eb894cfe", "scanner": "scanner-primary", "fingerprint": "3a749fedd2096e18", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-ae8d8599f6e24375", "level": "error", "message": {"text": "Dangling fetch: GET /api/focus-context (src/hooks/useFocusItems.js:31)"}, "properties": {"repobilityId": "a7671e0bf764bc49", "scanner": "scanner-primary", "fingerprint": "ae8d8599f6e24375", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dc3560ef7ccc2dc6", "level": "note", "message": {"text": "Unused endpoint: USE /api/sync"}, "properties": {"repobilityId": "f85656d314a50c16", "scanner": "scanner-primary", "fingerprint": "dc3560ef7ccc2dc6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-171501667618361a", "level": "note", "message": {"text": "Unused endpoint: USE /api/data"}, "properties": {"repobilityId": "633793ef5817143a", "scanner": "scanner-primary", "fingerprint": "171501667618361a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}