{"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-e4ad390b062c5d8a", "name": "Possibly dead Python function: seed_all", "shortDescription": {"text": "Possibly dead Python function: seed_all"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-78557c546d2cec0a", "name": "Possibly dead Python function: group_key", "shortDescription": {"text": "Possibly dead Python function: group_key"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2f87d60ca103223d", "name": "Possibly dead Python function: cleanup_expired_sessions", "shortDescription": {"text": "Possibly dead Python function: cleanup_expired_sessions"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-958a719d2f61e1c9", "name": "Possibly dead Python function: send_movers_summary", "shortDescription": {"text": "Possibly dead Python function: send_movers_summary"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-08cc49a211e7c362", "name": "Possibly dead Python function: send_upcoming_events", "shortDescription": {"text": "Possibly dead Python function: send_upcoming_events"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eb663114cfe917c2", "name": "Possibly dead Python function: send_end_of_day_summary", "shortDescription": {"text": "Possibly dead Python function: send_end_of_day_summary"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f4d60a54964f9b4b", "name": "Possibly dead Python function: shutdown_executor", "shortDescription": {"text": "Possibly dead Python function: shutdown_executor"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a1eed4c700191b9a", "name": "Possibly dead Python function: do_run_migrations", "shortDescription": {"text": "Possibly dead Python function: do_run_migrations"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-35ed4521c856d8f3", "name": "Possibly dead Python function: downgrade", "shortDescription": {"text": "Possibly dead Python function: downgrade"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-453c71e04c4769b0", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Header.tsx:225", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Header.tsx:225"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-eb23c590ff586023", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/ui/StockCard.tsx:53", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/ui/StockCard.tsx:53"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-93f33bc0aa2c5593", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/TradeReadiness.tsx:111", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/TradeReadiness.tsx:111"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e217f2bad1884414", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/NeedsAttention.tsx:39", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/NeedsAttention.tsx:39"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8602947dae7d06b2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/UpcomingEvents.tsx:76", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/UpcomingEvents.tsx:76"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ef5096648ad09890", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/MarketSnapshot.tsx:28", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/MarketSnapshot.tsx:28"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2b4198c407cb4d3c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/search/SearchBar.tsx:94", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/search/SearchBar.tsx:94"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-93b8bdad0e9244c6", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/watchlist/AddToWatchlistButton.tsx:76", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/watchlist/AddToWatchlistButton.tsx:76"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e9378d992095f421", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/watchlist/WatchlistItemRow.tsx:49", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/watchlist/WatchlistItemRow.tsx:49"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-443a99991f1a36d9", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/trigger/TriggerModal.tsx:225", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/trigger/TriggerModal.tsx:225"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2160230fa1d88779", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/equity/EquityEvents.tsx:210", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/equity/EquityEvents.tsx:210"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2a4acc5fa6069c20", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/playbook/page.tsx:119", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/playbook/page.tsx:119"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-74c144f49623d9c5", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/alerts/page.tsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/alerts/page.tsx:131"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ca4ee3a7353f77a0", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/market/page.tsx:116", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/market/page.tsx:116"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8f47ac7f08d17c17", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/trades/page.tsx:157", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/trades/page.tsx:157"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-589933530d0a8a37", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/watchlists/page.tsx:120", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/watchlists/page.tsx:120"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-edbc87ae6b0fd5d1", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/ratios/page.tsx:77", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/ratios/page.tsx:77"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-542b2eb06e9ea106", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/calendar/page.tsx:93", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/calendar/page.tsx:93"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8bdabd788e991ad8", "name": "Possible secret in frontend/src/lib/demo.ts", "shortDescription": {"text": "Possible secret in frontend/src/lib/demo.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-295b2bd3bc21289e", "name": "Possible secret in backend/scripts/seed_demo_users.py", "shortDescription": {"text": "Possible secret in backend/scripts/seed_demo_users.py"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-35b55e69271f521f", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/setup-node@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-de01526a30aa42a6", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/setup-python@v5 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "45 tests / 236 src (ratio 0.19)."}, "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 44 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 102 placeholder/mock markers across 27 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-17d866d91a7c451e", "name": "Agent instruction/config may expose a secret: CLAUDE.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8702df866b72fa6e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/lib/api/client.ts:209", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/lib/api/client.ts:209"}, "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-3c223d3db4c38119", "name": "Commented-code block (6 lines) in backend/app/services/alert.py:369", "shortDescription": {"text": "Commented-code block (6 lines) in backend/app/services/alert.py:369"}, "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-1b5a76780c3df9aa", "name": "1 env vars used in code but missing from .env.example", "shortDescription": {"text": "1 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `NEXT_PUBLIC_DEMO_MODE`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/api/v1/endpoints/trade.py:get_trade_service, backend/app/api/v1/endpoints/trade.py:get_trade\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f6b74d4f4b4e433d", "name": "FastAPI POST `refresh_tokens` without auth dependency \u2014 backend/app/api/v1/endpoints/auth.py:108", "shortDescription": {"text": "FastAPI POST `refresh_tokens` without auth dependency \u2014 backend/app/api/v1/endpoints/auth.py:108"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-665ac9f5a7ff9f02", "name": "Dangling fetch: POST /auth/logout-all (frontend/src/lib/api/client.ts:304)", "shortDescription": {"text": "Dangling fetch: POST /auth/logout-all (frontend/src/lib/api/client.ts:304)"}, "fullDescription": {"text": "`frontend/src/lib/api/client.ts:304` calls `POST /auth/logout-all` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/auth/logout-all`\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-a545642c13da91ef", "name": "Dangling fetch: POST /auth/me/change-password (frontend/src/lib/api/client.ts:329)", "shortDescription": {"text": "Dangling fetch: POST /auth/me/change-password (frontend/src/lib/api/client.ts:329)"}, "fullDescription": {"text": "`frontend/src/lib/api/client.ts:329` calls `POST /auth/me/change-password` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/auth/me/change-password`\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-43fc3d8a6508a186", "name": "Dangling fetch: DELETE /trades/${id} (frontend/src/lib/api/client.ts:1071)", "shortDescription": {"text": "Dangling fetch: DELETE /trades/${id} (frontend/src/lib/api/client.ts:1071)"}, "fullDescription": {"text": "`frontend/src/lib/api/client.ts:1071` calls `DELETE /trades/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/trades/<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-e7d77ba6ae5b84b9", "name": "Dangling fetch: DELETE /lessons/${id} (frontend/src/lib/api/client.ts:1119)", "shortDescription": {"text": "Dangling fetch: DELETE /lessons/${id} (frontend/src/lib/api/client.ts:1119)"}, "fullDescription": {"text": "`frontend/src/lib/api/client.ts:1119` calls `DELETE /lessons/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/lessons/<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-66484079e1e36505", "name": "Dangling fetch: DELETE /accounts/${id} (frontend/src/lib/api/client.ts:1153)", "shortDescription": {"text": "Dangling fetch: DELETE /accounts/${id} (frontend/src/lib/api/client.ts:1153)"}, "fullDescription": {"text": "`frontend/src/lib/api/client.ts:1153` calls `DELETE /accounts/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/accounts/<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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`backend/app/main.py` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-18725d50b4410b1a", "name": "Unused endpoint: GET /api/v1/schwab/status", "shortDescription": {"text": "Unused endpoint: GET /api/v1/schwab/status"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/schwab.py` declares `GET /api/v1/schwab/status` 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-09506d8d17003ab2", "name": "Unused endpoint: POST /api/v1/schwab/connect", "shortDescription": {"text": "Unused endpoint: POST /api/v1/schwab/connect"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/schwab.py` declares `POST /api/v1/schwab/connect` 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-991214c1023a9774", "name": "Unused endpoint: GET /api/v1/schwab/callback", "shortDescription": {"text": "Unused endpoint: GET /api/v1/schwab/callback"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/schwab.py` declares `GET /api/v1/schwab/callback` 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-cd198347740935e6", "name": "Unused endpoint: DELETE /api/v1/schwab/disconnect", "shortDescription": {"text": "Unused endpoint: DELETE /api/v1/schwab/disconnect"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/schwab.py` declares `DELETE /api/v1/schwab/disconnect` 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-bfdef6f2516e90c1", "name": "Unused endpoint: GET /api/v1/trades", "shortDescription": {"text": "Unused endpoint: GET /api/v1/trades"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `GET /api/v1/trades` 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-04b08f4a4e9a26c1", "name": "Unused endpoint: POST /api/v1/trades", "shortDescription": {"text": "Unused endpoint: POST /api/v1/trades"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `POST /api/v1/trades` 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-a6d82bc5801ef5bf", "name": "Unused endpoint: GET /api/v1/trades/portfolio", "shortDescription": {"text": "Unused endpoint: GET /api/v1/trades/portfolio"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `GET /api/v1/trades/portfolio` 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-e7bf82334a62e84c", "name": "Unused endpoint: GET /api/v1/trades/performance", "shortDescription": {"text": "Unused endpoint: GET /api/v1/trades/performance"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `GET /api/v1/trades/performance` 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-c83b21a46567ad44", "name": "Unused endpoint: GET /api/v1/trades/pairs", "shortDescription": {"text": "Unused endpoint: GET /api/v1/trades/pairs"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `GET /api/v1/trades/pairs` 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-eeafb04fe60956db", "name": "Unused endpoint: POST /api/v1/trades/position-size", "shortDescription": {"text": "Unused endpoint: POST /api/v1/trades/position-size"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `POST /api/v1/trades/position-size` 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-b60558bc75755ca9", "name": "Unused endpoint: GET /api/v1/trades/positions/{equity_id}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/trades/positions/{equity_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `GET /api/v1/trades/positions/{equity_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3a3995449bbcff8c", "name": "Unused endpoint: GET /api/v1/trades/{trade_id}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/trades/{trade_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `GET /api/v1/trades/{trade_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-90d0acded3f6fcfa", "name": "Unused endpoint: PUT /api/v1/trades/{trade_id}", "shortDescription": {"text": "Unused endpoint: PUT /api/v1/trades/{trade_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `PUT /api/v1/trades/{trade_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-774de89fb992ab33", "name": "Unused endpoint: DELETE /api/v1/trades/{trade_id}", "shortDescription": {"text": "Unused endpoint: DELETE /api/v1/trades/{trade_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/trade.py` declares `DELETE /api/v1/trades/{trade_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d4bc42396cbe9e48", "name": "Unused endpoint: GET /api/v1/accounts", "shortDescription": {"text": "Unused endpoint: GET /api/v1/accounts"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/account.py` declares `GET /api/v1/accounts` 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-162636f9d46093ba", "name": "Unused endpoint: POST /api/v1/accounts", "shortDescription": {"text": "Unused endpoint: POST /api/v1/accounts"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/account.py` declares `POST /api/v1/accounts` 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-e7bb75c0647583a8", "name": "Unused endpoint: GET /api/v1/accounts/{account_id}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/accounts/{account_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/account.py` declares `GET /api/v1/accounts/{account_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-760f955e5bd6b248", "name": "Unused endpoint: PUT /api/v1/accounts/{account_id}", "shortDescription": {"text": "Unused endpoint: PUT /api/v1/accounts/{account_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/account.py` declares `PUT /api/v1/accounts/{account_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d1c9d179ef24b04e", "name": "Unused endpoint: DELETE /api/v1/accounts/{account_id}", "shortDescription": {"text": "Unused endpoint: DELETE /api/v1/accounts/{account_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/account.py` declares `DELETE /api/v1/accounts/{account_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dc09ae5fff4bce8d", "name": "Unused endpoint: GET /api/v1/dashboard/needs-attention", "shortDescription": {"text": "Unused endpoint: GET /api/v1/dashboard/needs-attention"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/dashboard.py` declares `GET /api/v1/dashboard/needs-attention` 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-4d9ae461d59821c4", "name": "Unused endpoint: GET /api/v1/dashboard/trade-readiness", "shortDescription": {"text": "Unused endpoint: GET /api/v1/dashboard/trade-readiness"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/dashboard.py` declares `GET /api/v1/dashboard/trade-readiness` 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-8d791816e51888c1", "name": "Unused endpoint: GET /api/v1/dashboard/exposure", "shortDescription": {"text": "Unused endpoint: GET /api/v1/dashboard/exposure"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/dashboard.py` declares `GET /api/v1/dashboard/exposure` 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-443d24790d54a8b8", "name": "Unused endpoint: GET /api/v1/auth/registration-status", "shortDescription": {"text": "Unused endpoint: GET /api/v1/auth/registration-status"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `GET /api/v1/auth/registration-status` 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-92076c2733fc7c54", "name": "Unused endpoint: POST /api/v1/auth/register", "shortDescription": {"text": "Unused endpoint: POST /api/v1/auth/register"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `POST /api/v1/auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72530ed44ad5a45a", "name": "Unused endpoint: POST /api/v1/auth/login", "shortDescription": {"text": "Unused endpoint: POST /api/v1/auth/login"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `POST /api/v1/auth/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5be7411e2f955aa7", "name": "Unused endpoint: POST /api/v1/auth/refresh", "shortDescription": {"text": "Unused endpoint: POST /api/v1/auth/refresh"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `POST /api/v1/auth/refresh` 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-ae18eaed0cdc23e1", "name": "Unused endpoint: POST /api/v1/auth/logout", "shortDescription": {"text": "Unused endpoint: POST /api/v1/auth/logout"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `POST /api/v1/auth/logout` 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-1ab40fe0395c1861", "name": "Unused endpoint: POST /api/v1/auth/logout-all", "shortDescription": {"text": "Unused endpoint: POST /api/v1/auth/logout-all"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `POST /api/v1/auth/logout-all` 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-f28d5598f27ace34", "name": "Unused endpoint: GET /api/v1/auth/me", "shortDescription": {"text": "Unused endpoint: GET /api/v1/auth/me"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `GET /api/v1/auth/me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bbac82a8ea1450d7", "name": "Unused endpoint: PATCH /api/v1/auth/me", "shortDescription": {"text": "Unused endpoint: PATCH /api/v1/auth/me"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `PATCH /api/v1/auth/me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eb298a42c96e01b7", "name": "Unused endpoint: POST /api/v1/auth/me/change-password", "shortDescription": {"text": "Unused endpoint: POST /api/v1/auth/me/change-password"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `POST /api/v1/auth/me/change-password` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b605ff98a9b193fb", "name": "Unused endpoint: GET /api/v1/auth/me/sessions", "shortDescription": {"text": "Unused endpoint: GET /api/v1/auth/me/sessions"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/auth.py` declares `GET /api/v1/auth/me/sessions` 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-d04ddb18e3ae4ee3", "name": "Unused endpoint: GET /api/v1", "shortDescription": {"text": "Unused endpoint: GET /api/v1"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `GET /api/v1` 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-1434aac9fc27eba7", "name": "Unused endpoint: POST /api/v1", "shortDescription": {"text": "Unused endpoint: POST /api/v1"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `POST /api/v1` 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-4ffcddc0aed2bef9", "name": "Unused endpoint: GET /api/v1/quotes", "shortDescription": {"text": "Unused endpoint: GET /api/v1/quotes"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `GET /api/v1/quotes` 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-ee237eed4e473bbe", "name": "Unused endpoint: POST /api/v1/initialize", "shortDescription": {"text": "Unused endpoint: POST /api/v1/initialize"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `POST /api/v1/initialize` 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-7c9bd71548edce20", "name": "Unused endpoint: GET /api/v1/{ratio_id}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/{ratio_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `GET /api/v1/{ratio_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a63f64fdc60be362", "name": "Unused endpoint: PUT /api/v1/{ratio_id}", "shortDescription": {"text": "Unused endpoint: PUT /api/v1/{ratio_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `PUT /api/v1/{ratio_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a491043b31f2c025", "name": "Unused endpoint: DELETE /api/v1/{ratio_id}", "shortDescription": {"text": "Unused endpoint: DELETE /api/v1/{ratio_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `DELETE /api/v1/{ratio_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-520cffc4f9b300d1", "name": "Unused endpoint: GET /api/v1/{ratio_id}/quote", "shortDescription": {"text": "Unused endpoint: GET /api/v1/{ratio_id}/quote"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `GET /api/v1/{ratio_id}/quote` 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-b889bef332f6c3ec", "name": "Unused endpoint: GET /api/v1/{ratio_id}/history", "shortDescription": {"text": "Unused endpoint: GET /api/v1/{ratio_id}/history"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/ratio.py` declares `GET /api/v1/{ratio_id}/history` 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-61aa3137c01f5248", "name": "Unused endpoint: GET /api/v1/watchlists", "shortDescription": {"text": "Unused endpoint: GET /api/v1/watchlists"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `GET /api/v1/watchlists` 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-49264c2b6e9cb519", "name": "Unused endpoint: GET /api/v1/watchlists/movers", "shortDescription": {"text": "Unused endpoint: GET /api/v1/watchlists/movers"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `GET /api/v1/watchlists/movers` 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-174c1337cf658ba6", "name": "Unused endpoint: POST /api/v1/watchlists", "shortDescription": {"text": "Unused endpoint: POST /api/v1/watchlists"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `POST /api/v1/watchlists` 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-5d44a49a50e18e0d", "name": "Unused endpoint: GET /api/v1/watchlists/{watchlist_id}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/watchlists/{watchlist_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `GET /api/v1/watchlists/{watchlist_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d8c152a88ca55c1b", "name": "Unused endpoint: PUT /api/v1/watchlists/{watchlist_id}", "shortDescription": {"text": "Unused endpoint: PUT /api/v1/watchlists/{watchlist_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `PUT /api/v1/watchlists/{watchlist_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-672539d1bb024966", "name": "Unused endpoint: DELETE /api/v1/watchlists/{watchlist_id}", "shortDescription": {"text": "Unused endpoint: DELETE /api/v1/watchlists/{watchlist_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `DELETE /api/v1/watchlists/{watchlist_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-19dd5fdf6f5c16bd", "name": "Unused endpoint: POST /api/v1/watchlists/{watchlist_id}/items", "shortDescription": {"text": "Unused endpoint: POST /api/v1/watchlists/{watchlist_id}/items"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `POST /api/v1/watchlists/{watchlist_id}/items` 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-7522714021a62ce9", "name": "Unused endpoint: PUT /api/v1/watchlists/{watchlist_id}/items/{item_id}", "shortDescription": {"text": "Unused endpoint: PUT /api/v1/watchlists/{watchlist_id}/items/{item_id}"}, "fullDescription": {"text": "`backend/app/api/v1/endpoints/watchlist.py` declares `PUT /api/v1/watchlists/{watchlist_id}/items/{item_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/19889"}, "properties": {"repository": "smithadifd/investing_companion", "repoUrl": "https://github.com/smithadifd/investing_companion", "branch": "main"}, "results": [{"ruleId": "scanner-e4ad390b062c5d8a", "level": "note", "message": {"text": "Possibly dead Python function: seed_all"}, "properties": {"repobilityId": "277628269cadbb60", "scanner": "scanner-primary", "fingerprint": "e4ad390b062c5d8a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed_demo_data.py:402"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-78557c546d2cec0a", "level": "note", "message": {"text": "Possibly dead Python function: group_key"}, "properties": {"repobilityId": "9d2f53863b6248ea", "scanner": "scanner-primary", "fingerprint": "78557c546d2cec0a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/services/trade.py:552"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2f87d60ca103223d", "level": "note", "message": {"text": "Possibly dead Python function: cleanup_expired_sessions"}, "properties": {"repobilityId": "71e0198718c0d495", "scanner": "scanner-primary", "fingerprint": "2f87d60ca103223d", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/services/auth.py:249"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-958a719d2f61e1c9", "level": "note", "message": {"text": "Possibly dead Python function: send_movers_summary"}, "properties": {"repobilityId": "0367c67f2710a192", "scanner": "scanner-primary", "fingerprint": "958a719d2f61e1c9", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/services/notifications/discord.py:334"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-08cc49a211e7c362", "level": "note", "message": {"text": "Possibly dead Python function: send_upcoming_events"}, "properties": {"repobilityId": "736f6d4b05afce39", "scanner": "scanner-primary", "fingerprint": "08cc49a211e7c362", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/services/notifications/discord.py:429"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-eb663114cfe917c2", "level": "note", "message": {"text": "Possibly dead Python function: send_end_of_day_summary"}, "properties": {"repobilityId": "cad780132c290f6c", "scanner": "scanner-primary", "fingerprint": "eb663114cfe917c2", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/services/notifications/discord.py:529"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f4d60a54964f9b4b", "level": "note", "message": {"text": "Possibly dead Python function: shutdown_executor"}, "properties": {"repobilityId": "b4119a5d89a4b8c4", "scanner": "scanner-primary", "fingerprint": "f4d60a54964f9b4b", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/services/data_providers/yahoo.py:48"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a1eed4c700191b9a", "level": "note", "message": {"text": "Possibly dead Python function: do_run_migrations"}, "properties": {"repobilityId": "087acb17722cfd2f", "scanner": "scanner-primary", "fingerprint": "a1eed4c700191b9a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/alembic/env.py:56"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-35ed4521c856d8f3", "level": "note", "message": {"text": "Possibly dead Python function: downgrade"}, "properties": {"repobilityId": "c03debbf11efa0c5", "scanner": "scanner-primary", "fingerprint": "35ed4521c856d8f3", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/alembic/versions/20260201_005_add_economic_events.py:71"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-453c71e04c4769b0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/layout/Header.tsx:225"}, "properties": {"repobilityId": "f31794ffb87a08e8", "scanner": "scanner-primary", "fingerprint": "453c71e04c4769b0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eb23c590ff586023", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/ui/StockCard.tsx:53"}, "properties": {"repobilityId": "315371303d45a536", "scanner": "scanner-primary", "fingerprint": "eb23c590ff586023", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-93f33bc0aa2c5593", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/TradeReadiness.tsx:111"}, "properties": {"repobilityId": "21b39a5084294785", "scanner": "scanner-primary", "fingerprint": "93f33bc0aa2c5593", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e217f2bad1884414", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/NeedsAttention.tsx:39"}, "properties": {"repobilityId": "76861059b0a45f0c", "scanner": "scanner-primary", "fingerprint": "e217f2bad1884414", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8602947dae7d06b2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/UpcomingEvents.tsx:76"}, "properties": {"repobilityId": "f990ba14f137573a", "scanner": "scanner-primary", "fingerprint": "8602947dae7d06b2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ef5096648ad09890", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/dashboard/MarketSnapshot.tsx:28"}, "properties": {"repobilityId": "d909feb6375fcc9f", "scanner": "scanner-primary", "fingerprint": "ef5096648ad09890", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2b4198c407cb4d3c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/search/SearchBar.tsx:94"}, "properties": {"repobilityId": "3c7eb8d5d4742f27", "scanner": "scanner-primary", "fingerprint": "2b4198c407cb4d3c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-93b8bdad0e9244c6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/watchlist/AddToWatchlistButton.tsx:76"}, "properties": {"repobilityId": "48550c86cb1211e9", "scanner": "scanner-primary", "fingerprint": "93b8bdad0e9244c6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e9378d992095f421", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/watchlist/WatchlistItemRow.tsx:49"}, "properties": {"repobilityId": "dd5cd9cea6838671", "scanner": "scanner-primary", "fingerprint": "e9378d992095f421", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-443a99991f1a36d9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/trigger/TriggerModal.tsx:225"}, "properties": {"repobilityId": "a657faae7d4e7636", "scanner": "scanner-primary", "fingerprint": "443a99991f1a36d9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2160230fa1d88779", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/equity/EquityEvents.tsx:210"}, "properties": {"repobilityId": "458b79737ff7f65a", "scanner": "scanner-primary", "fingerprint": "2160230fa1d88779", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2a4acc5fa6069c20", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/playbook/page.tsx:119"}, "properties": {"repobilityId": "7cc95f2bd4db8111", "scanner": "scanner-primary", "fingerprint": "2a4acc5fa6069c20", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-74c144f49623d9c5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/alerts/page.tsx:131"}, "properties": {"repobilityId": "d925e52a600e9816", "scanner": "scanner-primary", "fingerprint": "74c144f49623d9c5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca4ee3a7353f77a0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/market/page.tsx:116"}, "properties": {"repobilityId": "c5d3aec43a04b6a5", "scanner": "scanner-primary", "fingerprint": "ca4ee3a7353f77a0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8f47ac7f08d17c17", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/trades/page.tsx:157"}, "properties": {"repobilityId": "bab48eafec5e74b9", "scanner": "scanner-primary", "fingerprint": "8f47ac7f08d17c17", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-589933530d0a8a37", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/watchlists/page.tsx:120"}, "properties": {"repobilityId": "ac5affeb8f1369e8", "scanner": "scanner-primary", "fingerprint": "589933530d0a8a37", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-edbc87ae6b0fd5d1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/ratios/page.tsx:77"}, "properties": {"repobilityId": "85d863fb327dcc07", "scanner": "scanner-primary", "fingerprint": "edbc87ae6b0fd5d1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-542b2eb06e9ea106", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/app/calendar/page.tsx:93"}, "properties": {"repobilityId": "f95fd6cc37eea8a6", "scanner": "scanner-primary", "fingerprint": "542b2eb06e9ea106", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-8bdabd788e991ad8", "level": "error", "message": {"text": "Possible secret in frontend/src/lib/demo.ts"}, "properties": {"repobilityId": "aa9ba965e2919dd3", "scanner": "scanner-primary", "fingerprint": "8bdabd788e991ad8", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/lib/demo.ts"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-295b2bd3bc21289e", "level": "error", "message": {"text": "Possible secret in backend/scripts/seed_demo_users.py"}, "properties": {"repobilityId": "6732e86a00b97f2c", "scanner": "scanner-primary", "fingerprint": "295b2bd3bc21289e", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/scripts/seed_demo_users.py"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-35b55e69271f521f", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "0cedcc5b0bd36659", "scanner": "scanner-primary", "fingerprint": "35b55e69271f521f", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docs-site.yml"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-35b55e69271f521f", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e4308e6a60e739d8", "scanner": "scanner-primary", "fingerprint": "35b55e69271f521f", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docs-site.yml"}, "region": {"startLine": 47}}}]}, {"ruleId": "scanner-35b55e69271f521f", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "c0336c7b3abd566d", "scanner": "scanner-primary", "fingerprint": "35b55e69271f521f", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docs-site.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-de01526a30aa42a6", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "7cd8e342944407e1", "scanner": "scanner-primary", "fingerprint": "de01526a30aa42a6", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/docs-site.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "04f57d208548fcef", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 53}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 85}}}]}, {"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-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "c996ab74b929874b", "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": "882d1231de82d6d4", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "6aea170d2e7b463d", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "7e071daa567468cb", "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": "bf45f9f5a9bc396d", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-17d866d91a7c451e", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: CLAUDE.md"}, "properties": {"repobilityId": "ccce5984e58a48f0", "scanner": "scanner-primary", "fingerprint": "17d866d91a7c451e", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 152}}}]}, {"ruleId": "scanner-8702df866b72fa6e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/lib/api/client.ts:209"}, "properties": {"repobilityId": "694cd1fd61ac2371", "scanner": "scanner-primary", "fingerprint": "8702df866b72fa6e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3c223d3db4c38119", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/app/services/alert.py:369"}, "properties": {"repobilityId": "e7fb78d4bdb18a9d", "scanner": "scanner-primary", "fingerprint": "3c223d3db4c38119", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1b5a76780c3df9aa", "level": "none", "message": {"text": "1 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d04379b337b44a15", "scanner": "scanner-primary", "fingerprint": "1b5a76780c3df9aa", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "b682a85f143ee269", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "bb660e4c96452fa1", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "0f30828887bf97f9", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "fb07e55438edde1d", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "6b3e5373e9a01f7b", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "34c409abdcd61b82", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "20058fd4714cee3c", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "928f098ad2dce36a", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "0978bea1f05e2382", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "5c7503616dfa5572", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "f82907b3d3508e0a", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "5a4e4f8e4f5534ef", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "11c704cc007e4076", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "3363236484abb7da", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "0671d99682fbe687", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "fdaf54ee456f0104", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "d37e20d1d12da5ba", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "56aa4b0fb22190de", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "e10ef386262da0a3", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-f6b74d4f4b4e433d", "level": "error", "message": {"text": "FastAPI POST `refresh_tokens` without auth dependency \u2014 backend/app/api/v1/endpoints/auth.py:108"}, "properties": {"repobilityId": "1054d34668c486fc", "scanner": "scanner-primary", "fingerprint": "f6b74d4f4b4e433d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/endpoints/auth.py"}, "region": {"startLine": 108}}}]}, {"ruleId": "scanner-665ac9f5a7ff9f02", "level": "error", "message": {"text": "Dangling fetch: POST /auth/logout-all (frontend/src/lib/api/client.ts:304)"}, "properties": {"repobilityId": "664837347bc715c2", "scanner": "scanner-primary", "fingerprint": "665ac9f5a7ff9f02", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a545642c13da91ef", "level": "error", "message": {"text": "Dangling fetch: POST /auth/me/change-password (frontend/src/lib/api/client.ts:329)"}, "properties": {"repobilityId": "ef68a4ff0ec1c228", "scanner": "scanner-primary", "fingerprint": "a545642c13da91ef", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-43fc3d8a6508a186", "level": "error", "message": {"text": "Dangling fetch: DELETE /trades/${id} (frontend/src/lib/api/client.ts:1071)"}, "properties": {"repobilityId": "d0714a81dac95229", "scanner": "scanner-primary", "fingerprint": "43fc3d8a6508a186", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e7d77ba6ae5b84b9", "level": "error", "message": {"text": "Dangling fetch: DELETE /lessons/${id} (frontend/src/lib/api/client.ts:1119)"}, "properties": {"repobilityId": "9b1c272ac709a48b", "scanner": "scanner-primary", "fingerprint": "e7d77ba6ae5b84b9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-66484079e1e36505", "level": "error", "message": {"text": "Dangling fetch: DELETE /accounts/${id} (frontend/src/lib/api/client.ts:1153)"}, "properties": {"repobilityId": "8878c15beb645d8e", "scanner": "scanner-primary", "fingerprint": "66484079e1e36505", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "9a7ab29051c0367b", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-18725d50b4410b1a", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/schwab/status"}, "properties": {"repobilityId": "c3b5e6f81d03782c", "scanner": "scanner-primary", "fingerprint": "18725d50b4410b1a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-09506d8d17003ab2", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/schwab/connect"}, "properties": {"repobilityId": "fb8ded432d616dd1", "scanner": "scanner-primary", "fingerprint": "09506d8d17003ab2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-991214c1023a9774", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/schwab/callback"}, "properties": {"repobilityId": "edb0f8ef850f2f7b", "scanner": "scanner-primary", "fingerprint": "991214c1023a9774", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd198347740935e6", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/v1/schwab/disconnect"}, "properties": {"repobilityId": "641c6a550d9322a1", "scanner": "scanner-primary", "fingerprint": "cd198347740935e6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bfdef6f2516e90c1", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/trades"}, "properties": {"repobilityId": "885cbc44d2f88ff7", "scanner": "scanner-primary", "fingerprint": "bfdef6f2516e90c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-04b08f4a4e9a26c1", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/trades"}, "properties": {"repobilityId": "c3cecc800b11e13d", "scanner": "scanner-primary", "fingerprint": "04b08f4a4e9a26c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a6d82bc5801ef5bf", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/trades/portfolio"}, "properties": {"repobilityId": "82f665cc75084ad4", "scanner": "scanner-primary", "fingerprint": "a6d82bc5801ef5bf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e7bf82334a62e84c", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/trades/performance"}, "properties": {"repobilityId": "b5ce2a2ca8b72714", "scanner": "scanner-primary", "fingerprint": "e7bf82334a62e84c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c83b21a46567ad44", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/trades/pairs"}, "properties": {"repobilityId": "d9421a04e507e248", "scanner": "scanner-primary", "fingerprint": "c83b21a46567ad44", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eeafb04fe60956db", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/trades/position-size"}, "properties": {"repobilityId": "1190683e9567f12d", "scanner": "scanner-primary", "fingerprint": "eeafb04fe60956db", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b60558bc75755ca9", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/trades/positions/{equity_id}"}, "properties": {"repobilityId": "aa9fdcc6d0567080", "scanner": "scanner-primary", "fingerprint": "b60558bc75755ca9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3a3995449bbcff8c", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/trades/{trade_id}"}, "properties": {"repobilityId": "14992af49ae59603", "scanner": "scanner-primary", "fingerprint": "3a3995449bbcff8c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-90d0acded3f6fcfa", "level": "note", "message": {"text": "Unused endpoint: PUT /api/v1/trades/{trade_id}"}, "properties": {"repobilityId": "5a0e998db73a40c6", "scanner": "scanner-primary", "fingerprint": "90d0acded3f6fcfa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-774de89fb992ab33", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/v1/trades/{trade_id}"}, "properties": {"repobilityId": "2a50f943cf86bf01", "scanner": "scanner-primary", "fingerprint": "774de89fb992ab33", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d4bc42396cbe9e48", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/accounts"}, "properties": {"repobilityId": "4e0f1b0446932de6", "scanner": "scanner-primary", "fingerprint": "d4bc42396cbe9e48", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-162636f9d46093ba", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/accounts"}, "properties": {"repobilityId": "69ac168c14fdda17", "scanner": "scanner-primary", "fingerprint": "162636f9d46093ba", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e7bb75c0647583a8", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/accounts/{account_id}"}, "properties": {"repobilityId": "bbea4976d2ccfe43", "scanner": "scanner-primary", "fingerprint": "e7bb75c0647583a8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-760f955e5bd6b248", "level": "note", "message": {"text": "Unused endpoint: PUT /api/v1/accounts/{account_id}"}, "properties": {"repobilityId": "11eb12e2f77c2fb8", "scanner": "scanner-primary", "fingerprint": "760f955e5bd6b248", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d1c9d179ef24b04e", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/v1/accounts/{account_id}"}, "properties": {"repobilityId": "95f752b7db7b6524", "scanner": "scanner-primary", "fingerprint": "d1c9d179ef24b04e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dc09ae5fff4bce8d", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/dashboard/needs-attention"}, "properties": {"repobilityId": "598fabb624ba1767", "scanner": "scanner-primary", "fingerprint": "dc09ae5fff4bce8d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d9ae461d59821c4", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/dashboard/trade-readiness"}, "properties": {"repobilityId": "d2826e0ac1f43bbb", "scanner": "scanner-primary", "fingerprint": "4d9ae461d59821c4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d791816e51888c1", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/dashboard/exposure"}, "properties": {"repobilityId": "b99c475219a4e8ae", "scanner": "scanner-primary", "fingerprint": "8d791816e51888c1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-443d24790d54a8b8", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/auth/registration-status"}, "properties": {"repobilityId": "f1665a5b13e48e48", "scanner": "scanner-primary", "fingerprint": "443d24790d54a8b8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-92076c2733fc7c54", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/auth/register"}, "properties": {"repobilityId": "023fe7f12a0699b0", "scanner": "scanner-primary", "fingerprint": "92076c2733fc7c54", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-72530ed44ad5a45a", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/auth/login"}, "properties": {"repobilityId": "1736f865352d7c57", "scanner": "scanner-primary", "fingerprint": "72530ed44ad5a45a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5be7411e2f955aa7", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/auth/refresh"}, "properties": {"repobilityId": "2d5f26a32bd7ad80", "scanner": "scanner-primary", "fingerprint": "5be7411e2f955aa7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ae18eaed0cdc23e1", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/auth/logout"}, "properties": {"repobilityId": "10f809d94b8a6adc", "scanner": "scanner-primary", "fingerprint": "ae18eaed0cdc23e1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ab40fe0395c1861", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/auth/logout-all"}, "properties": {"repobilityId": "50acb9ef5cf8ac8e", "scanner": "scanner-primary", "fingerprint": "1ab40fe0395c1861", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f28d5598f27ace34", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/auth/me"}, "properties": {"repobilityId": "32c1ee08e76c82da", "scanner": "scanner-primary", "fingerprint": "f28d5598f27ace34", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bbac82a8ea1450d7", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/v1/auth/me"}, "properties": {"repobilityId": "ac929eca2e052425", "scanner": "scanner-primary", "fingerprint": "bbac82a8ea1450d7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eb298a42c96e01b7", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/auth/me/change-password"}, "properties": {"repobilityId": "03022a1ae42dbae4", "scanner": "scanner-primary", "fingerprint": "eb298a42c96e01b7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b605ff98a9b193fb", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/auth/me/sessions"}, "properties": {"repobilityId": "89c99824f664a2cb", "scanner": "scanner-primary", "fingerprint": "b605ff98a9b193fb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d04ddb18e3ae4ee3", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1"}, "properties": {"repobilityId": "3c7882b25a3eca50", "scanner": "scanner-primary", "fingerprint": "d04ddb18e3ae4ee3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1434aac9fc27eba7", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1"}, "properties": {"repobilityId": "b0016d84dd727060", "scanner": "scanner-primary", "fingerprint": "1434aac9fc27eba7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ffcddc0aed2bef9", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/quotes"}, "properties": {"repobilityId": "93c37852280b90eb", "scanner": "scanner-primary", "fingerprint": "4ffcddc0aed2bef9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ee237eed4e473bbe", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/initialize"}, "properties": {"repobilityId": "c0e3bca71ad0c6e8", "scanner": "scanner-primary", "fingerprint": "ee237eed4e473bbe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c9bd71548edce20", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/{ratio_id}"}, "properties": {"repobilityId": "a55cbc2e6d7a66e1", "scanner": "scanner-primary", "fingerprint": "7c9bd71548edce20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a63f64fdc60be362", "level": "note", "message": {"text": "Unused endpoint: PUT /api/v1/{ratio_id}"}, "properties": {"repobilityId": "65b7eb1cab6a94de", "scanner": "scanner-primary", "fingerprint": "a63f64fdc60be362", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a491043b31f2c025", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/v1/{ratio_id}"}, "properties": {"repobilityId": "7bfd2ddef3634f13", "scanner": "scanner-primary", "fingerprint": "a491043b31f2c025", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-520cffc4f9b300d1", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/{ratio_id}/quote"}, "properties": {"repobilityId": "5056e7390a874d5c", "scanner": "scanner-primary", "fingerprint": "520cffc4f9b300d1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b889bef332f6c3ec", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/{ratio_id}/history"}, "properties": {"repobilityId": "38a8fea39f8734b7", "scanner": "scanner-primary", "fingerprint": "b889bef332f6c3ec", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-61aa3137c01f5248", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/watchlists"}, "properties": {"repobilityId": "7fd127c33ddbb609", "scanner": "scanner-primary", "fingerprint": "61aa3137c01f5248", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-49264c2b6e9cb519", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/watchlists/movers"}, "properties": {"repobilityId": "4cac6f77e23b694d", "scanner": "scanner-primary", "fingerprint": "49264c2b6e9cb519", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-174c1337cf658ba6", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/watchlists"}, "properties": {"repobilityId": "2a1f7be4fa46d674", "scanner": "scanner-primary", "fingerprint": "174c1337cf658ba6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5d44a49a50e18e0d", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/watchlists/{watchlist_id}"}, "properties": {"repobilityId": "3dd91651f59b2261", "scanner": "scanner-primary", "fingerprint": "5d44a49a50e18e0d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d8c152a88ca55c1b", "level": "note", "message": {"text": "Unused endpoint: PUT /api/v1/watchlists/{watchlist_id}"}, "properties": {"repobilityId": "784e948ff661fcae", "scanner": "scanner-primary", "fingerprint": "d8c152a88ca55c1b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-672539d1bb024966", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/v1/watchlists/{watchlist_id}"}, "properties": {"repobilityId": "0f1fc42c7d3ff351", "scanner": "scanner-primary", "fingerprint": "672539d1bb024966", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-19dd5fdf6f5c16bd", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/watchlists/{watchlist_id}/items"}, "properties": {"repobilityId": "e6637ab1e25d5f2b", "scanner": "scanner-primary", "fingerprint": "19dd5fdf6f5c16bd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7522714021a62ce9", "level": "note", "message": {"text": "Unused endpoint: PUT /api/v1/watchlists/{watchlist_id}/items/{item_id}"}, "properties": {"repobilityId": "e5a3c9f722ee8193", "scanner": "scanner-primary", "fingerprint": "7522714021a62ce9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}