{"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-ea5d133746513182", "name": "Stray `console.log` in TS/JS \u2014 server/index.ts:57", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/index.ts:57"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cc8bf988b17085d5", "name": "Stray `console.log` in TS/JS \u2014 server/lib/redis.ts:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/redis.ts:29"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-efbb911a6a7c139b", "name": "Stray `console.log` in TS/JS \u2014 server/lib/llm.ts:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/llm.ts:21"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ea19abe0fcf422b2", "name": "Stray `console.log` in TS/JS \u2014 server/routes/analysis.ts:115", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/analysis.ts:115"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f38afad260dfa4ed", "name": "Stray `console.log` in TS/JS \u2014 server/routes/agent.ts:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/agent.ts:21"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1d01cb39c7263586", "name": "Stray `console.log` in TS/JS \u2014 server/services/hotlist.ts:181", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/services/hotlist.ts:181"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7d0fc5ce55c770af", "name": "Stray `console.log` in TS/JS \u2014 server/services/ashare.ts:1051", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/services/ashare.ts:1051"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d51daf3e4eaf815c", "name": "Stray `console.log` in TS/JS \u2014 server/services/kaipanla.ts:76", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/services/kaipanla.ts:76"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b85390615b8cadee", "name": "Stray `console.log` in TS/JS \u2014 server/db/pgDatabase.ts:143", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/db/pgDatabase.ts:143"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-17223f38aebae018", "name": "Stray `console.log` in TS/JS \u2014 server/graph/graphSchema.ts:125", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/graph/graphSchema.ts:125"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5daf174cfa775ba1", "name": "Stray `console.log` in TS/JS \u2014 src/agent/components/ChatPanel.tsx:335", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/agent/components/ChatPanel.tsx:335"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-53775e9ee21910ef", "name": "Stray `console.log` in TS/JS \u2014 src/agent/pipeline/middleware/logging.middleware.ts:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/agent/pipeline/middleware/logging.middleware.ts:17"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7c1696e669d5cb52", "name": "Stray `console.log` in TS/JS \u2014 src/agent/skills/skill.executor.ts:135", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/agent/skills/skill.executor.ts:135"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4c2787e7c56c4664", "name": "Stray `console.log` in TS/JS \u2014 src/hooks/useRagSync.ts:48", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/hooks/useRagSync.ts:48"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2f261a032a1437b1", "name": "Stray `console.log` in TS/JS \u2014 src/hooks/useGraphSync.ts:56", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/hooks/useGraphSync.ts:56"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e23f2c640009fc15", "name": "Insecure pattern 'node_child_process' in scripts/sync-cn-finance.mjs:17", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/sync-cn-finance.mjs:17"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "41 tests / 177 src (ratio 0.23)."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6fd3a1350a723ee5", "name": "Node manifest has dependencies but no lockfile: mcp-servers/trade-db/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/trade-db/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5c8e2a30c962195c", "name": "Node manifest has dependencies but no lockfile: mcp-servers/rag/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/rag/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fe7b0e1d1e8d21cd", "name": "Node manifest has dependencies but no lockfile: mcp-servers/market-data/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/market-data/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7fa10159be791d8d", "name": "Node manifest has dependencies but no lockfile: mcp-servers/memory-graph/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/memory-graph/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 40 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 28 placeholder/mock markers across 12 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bf3fbb2bfc8185d8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 mcp-servers/market-data/src/index.mjs:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 mcp-servers/market-data/src/index.mjs:18"}, "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-5a25c321f3cdc1d5", "name": "Commented-code block (9 lines) in server/lib/cache.ts:6", "shortDescription": {"text": "Commented-code block (9 lines) in server/lib/cache.ts:6"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-56965b1da63274d7", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/llm.ts:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/llm.ts:37"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cc34d550a4917eb8", "name": "Commented-code block (5 lines) in server/services/emQuotes.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in server/services/emQuotes.ts:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-46618ff4818ec134", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/webSearch.ts:27", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/webSearch.ts:27"}, "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-8a9499f2ba077f45", "name": "Legacy-named symbol `json_v2` in server/services/ashare.ts:338", "shortDescription": {"text": "Legacy-named symbol `json_v2` in server/services/ashare.ts:338"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e435735d394fdb29", "name": "Commented-code block (5 lines) in server/services/ashare.ts:912", "shortDescription": {"text": "Commented-code block (5 lines) in server/services/ashare.ts:912"}, "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-a0e887fcb81ab9e8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/ashare.ts:163", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/ashare.ts:163"}, "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-f9f594edf4cf0070", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/macro.ts:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/macro.ts:65"}, "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-b39f392b595dbaef", "name": "Commented-code block (6 lines) in server/services/kaipanla.ts:1", "shortDescription": {"text": "Commented-code block (6 lines) in server/services/kaipanla.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8b1e440b8dc6ac9a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/llmClient.ts:30", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/llmClient.ts:30"}, "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-f79a7d9f36ca454d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/pipeline/middleware/memory.middleware.ts:97", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/pipeline/middleware/memory.middleware.ts:97"}, "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-e815605432d89ed0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getLimitPool.ts:25", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getLimitPool.ts:25"}, "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-e61dd54cf08a5e5c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockNews.ts:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockNews.ts:32"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4b6dec872c6296b4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/analyzeWithTheory.ts:45", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/analyzeWithTheory.ts:45"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-10c373bbe5d5462d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/hybridSearch.ts:39", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/hybridSearch.ts:39"}, "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-be9fcdc3d0cb5639", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getFundamentalReport.ts:46", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getFundamentalReport.ts:46"}, "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-7b4fe893f1349c50", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getMacroIndicators.ts:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getMacroIndicators.ts:17"}, "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-154efa553fb2e568", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockKline.ts:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockKline.ts:38"}, "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-4df36165c60afa8b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockFundamentals.ts:26", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockFundamentals.ts:26"}, "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-3e155d012865b34b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getMarketBreadth.ts:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getMarketBreadth.ts:17"}, "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-f1c8ca2897e17984", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/semanticSearch.ts:37", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/semanticSearch.ts:37"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-47779620a8bcbd87", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getIndexTrends.ts:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getIndexTrends.ts:21"}, "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-acf6f8b32d2a821c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getNewsSummary.ts:15", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getNewsSummary.ts:15"}, "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-186fa0dff0fb4fda", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockQuote.ts:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockQuote.ts:28"}, "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-d81fe1a064915544", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/screenStocks.ts:43", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/screenStocks.ts:43"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e0f9a5581b8f2c66", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/searchWeb.ts:32", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/searchWeb.ts:32"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9a1c82fae49cf8de", "name": "Legacy-named symbol `pruneOld` in src/utils/marketHistory.ts:90", "shortDescription": {"text": "Legacy-named symbol `pruneOld` in src/utils/marketHistory.ts:90"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-40fb2def2c927a06", "name": "Commented-code block (5 lines) in src/store/persistence.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in src/store/persistence.ts:3"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-59b992d62d86a65a", "name": "25 env vars used in code but missing from .env.example", "shortDescription": {"text": "25 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `CLAUDE_API_KEY`, `CLAUDE_API_URL`, `CLAUDE_MODEL`, `CN_FINANCE_SRC`, `CORS_ORIGINS`, `EMBEDDING_MODEL`, `GEMINI_API_KEY`, `GEMINI_API_URL` + 17 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-342b815047f1ca0f", "name": "Unused endpoint: GET /api/mcp/rag/status", "shortDescription": {"text": "Unused endpoint: GET /api/mcp/rag/status"}, "fullDescription": {"text": "`server/routes/mcp.ts` declares `GET /api/mcp/rag/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-28ea84cdf44b8b63", "name": "Unused endpoint: GET /api/mcp/graph/stats", "shortDescription": {"text": "Unused endpoint: GET /api/mcp/graph/stats"}, "fullDescription": {"text": "`server/routes/mcp.ts` declares `GET /api/mcp/graph/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1cb805b41f26da35", "name": "Unused endpoint: PUT /api/memory/:userId", "shortDescription": {"text": "Unused endpoint: PUT /api/memory/:userId"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `PUT /api/memory/:userId` 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-1198dec5ef131620", "name": "Unused endpoint: PATCH /api/memory/:userId/profile", "shortDescription": {"text": "Unused endpoint: PATCH /api/memory/:userId/profile"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `PATCH /api/memory/:userId/profile` 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-ab314172fb2a6b26", "name": "Unused endpoint: POST /api/memory/:userId/plans", "shortDescription": {"text": "Unused endpoint: POST /api/memory/:userId/plans"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `POST /api/memory/:userId/plans` 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-d37efb71b70bc6ad", "name": "Unused endpoint: PATCH /api/memory/:userId/plans/:planId", "shortDescription": {"text": "Unused endpoint: PATCH /api/memory/:userId/plans/:planId"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `PATCH /api/memory/:userId/plans/:planId` 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-191b4cd103025c12", "name": "Unused endpoint: PATCH /api/memory/:userId/market", "shortDescription": {"text": "Unused endpoint: PATCH /api/memory/:userId/market"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `PATCH /api/memory/:userId/market` 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-f42094d323d603da", "name": "Unused endpoint: GET /api/memory-enhanced/:userId", "shortDescription": {"text": "Unused endpoint: GET /api/memory-enhanced/:userId"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `GET /api/memory-enhanced/:userId` 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-08da66f43edce44d", "name": "Unused endpoint: PATCH /api/memory-enhanced/:userId/profile", "shortDescription": {"text": "Unused endpoint: PATCH /api/memory-enhanced/:userId/profile"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `PATCH /api/memory-enhanced/:userId/profile` 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-832932bca23a0bf4", "name": "Unused endpoint: POST /api/memory-enhanced/:userId/infer-profile", "shortDescription": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/infer-profile"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `POST /api/memory-enhanced/:userId/infer-profile` 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-53ccda2c2fe41011", "name": "Unused endpoint: POST /api/memory-enhanced/:userId/lessons", "shortDescription": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/lessons"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `POST /api/memory-enhanced/:userId/lessons` 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-ca80634db75d594d", "name": "Unused endpoint: POST /api/memory-enhanced/:userId/patterns", "shortDescription": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/patterns"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `POST /api/memory-enhanced/:userId/patterns` 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-ac0e711d2cb3828f", "name": "Unused endpoint: POST /api/memory-enhanced/:userId/decisions", "shortDescription": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/decisions"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `POST /api/memory-enhanced/:userId/decisions` 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-da745a358147aece", "name": "Unused endpoint: POST /api/memory-enhanced/:userId/actions", "shortDescription": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/actions"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `POST /api/memory-enhanced/:userId/actions` 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-1aa9cc6b4dfed331", "name": "Unused endpoint: PATCH /api/memory-enhanced/:userId/actions/:actionId", "shortDescription": {"text": "Unused endpoint: PATCH /api/memory-enhanced/:userId/actions/:actionId"}, "fullDescription": {"text": "`server/routes/memory.ts` declares `PATCH /api/memory-enhanced/:userId/actions/:actionId` 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-a4bf36abff244783", "name": "Unused endpoint: POST /api/agent/chat", "shortDescription": {"text": "Unused endpoint: POST /api/agent/chat"}, "fullDescription": {"text": "`server/routes/agent.ts` declares `POST /api/agent/chat` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9802182873141fdb", "name": "Unused endpoint: GET /api/db/trades", "shortDescription": {"text": "Unused endpoint: GET /api/db/trades"}, "fullDescription": {"text": "`server/routes/db.ts` declares `GET /api/db/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-114349b996b8c38e", "name": "Unused endpoint: POST /api/db/trades", "shortDescription": {"text": "Unused endpoint: POST /api/db/trades"}, "fullDescription": {"text": "`server/routes/db.ts` declares `POST /api/db/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-027eceb0fb349027", "name": "Unused endpoint: GET /api/db/trade-groups", "shortDescription": {"text": "Unused endpoint: GET /api/db/trade-groups"}, "fullDescription": {"text": "`server/routes/db.ts` declares `GET /api/db/trade-groups` 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-e1eaa47c801455cf", "name": "Unused endpoint: POST /api/db/trade-groups", "shortDescription": {"text": "Unused endpoint: POST /api/db/trade-groups"}, "fullDescription": {"text": "`server/routes/db.ts` declares `POST /api/db/trade-groups` 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-4d4c10d6e56e69ad", "name": "Unused endpoint: GET /api/db/review-notes/:groupId", "shortDescription": {"text": "Unused endpoint: GET /api/db/review-notes/:groupId"}, "fullDescription": {"text": "`server/routes/db.ts` declares `GET /api/db/review-notes/:groupId` 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-cd5edcfc2b3add79", "name": "Unused endpoint: PUT /api/db/review-notes/:groupId", "shortDescription": {"text": "Unused endpoint: PUT /api/db/review-notes/:groupId"}, "fullDescription": {"text": "`server/routes/db.ts` declares `PUT /api/db/review-notes/:groupId` 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-1c2bf402aeaa2f3c", "name": "Unused endpoint: POST /api/db/import-batches", "shortDescription": {"text": "Unused endpoint: POST /api/db/import-batches"}, "fullDescription": {"text": "`server/routes/db.ts` declares `POST /api/db/import-batches` 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-8d667555e0c8f80d", "name": "Unused endpoint: GET /api/ashare", "shortDescription": {"text": "Unused endpoint: GET /api/ashare"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/ashare` 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-7ef95d4e9930e8fe", "name": "Unused endpoint: GET /api/hk", "shortDescription": {"text": "Unused endpoint: GET /api/hk"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/hk` 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-7fd3224443b63cdb", "name": "Unused endpoint: GET /api/hk/quote", "shortDescription": {"text": "Unused endpoint: GET /api/hk/quote"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/hk/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-272e31e77f705acb", "name": "Unused endpoint: GET /api/us", "shortDescription": {"text": "Unused endpoint: GET /api/us"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/us` 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-39eb0c8fa833690a", "name": "Unused endpoint: GET /api/us/quote", "shortDescription": {"text": "Unused endpoint: GET /api/us/quote"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/us/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-bb7804b1661d7dbf", "name": "Unused endpoint: GET /api/hotlist", "shortDescription": {"text": "Unused endpoint: GET /api/hotlist"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/hotlist` 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-8b5061676d4813b8", "name": "Unused endpoint: GET /api/highs", "shortDescription": {"text": "Unused endpoint: GET /api/highs"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/highs` 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-bd9ca55dfdc250fc", "name": "Unused endpoint: GET /api/sentiment", "shortDescription": {"text": "Unused endpoint: GET /api/sentiment"}, "fullDescription": {"text": "`server/routes/market.ts` declares `GET /api/sentiment` 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/23105"}, "properties": {"repository": "xzy025/wax-wane", "repoUrl": "https://github.com/xzy025/wax-wane", "branch": "main"}, "results": [{"ruleId": "scanner-ea5d133746513182", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/index.ts:57"}, "properties": {"repobilityId": "b4961a877930fd2f", "scanner": "scanner-primary", "fingerprint": "ea5d133746513182", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cc8bf988b17085d5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/redis.ts:29"}, "properties": {"repobilityId": "759efacbe0817d5c", "scanner": "scanner-primary", "fingerprint": "cc8bf988b17085d5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-efbb911a6a7c139b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/llm.ts:21"}, "properties": {"repobilityId": "48d97b867ce3bcc2", "scanner": "scanner-primary", "fingerprint": "efbb911a6a7c139b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ea19abe0fcf422b2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/analysis.ts:115"}, "properties": {"repobilityId": "3edd53aab2b7936a", "scanner": "scanner-primary", "fingerprint": "ea19abe0fcf422b2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f38afad260dfa4ed", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/routes/agent.ts:21"}, "properties": {"repobilityId": "87b6f68613373b3d", "scanner": "scanner-primary", "fingerprint": "f38afad260dfa4ed", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1d01cb39c7263586", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/services/hotlist.ts:181"}, "properties": {"repobilityId": "a89dc8f2068743ed", "scanner": "scanner-primary", "fingerprint": "1d01cb39c7263586", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7d0fc5ce55c770af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/services/ashare.ts:1051"}, "properties": {"repobilityId": "ca2c0f47d299a193", "scanner": "scanner-primary", "fingerprint": "7d0fc5ce55c770af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d51daf3e4eaf815c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/services/kaipanla.ts:76"}, "properties": {"repobilityId": "134761d43fa4dfd2", "scanner": "scanner-primary", "fingerprint": "d51daf3e4eaf815c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b85390615b8cadee", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/db/pgDatabase.ts:143"}, "properties": {"repobilityId": "298c9f9706f4a5e3", "scanner": "scanner-primary", "fingerprint": "b85390615b8cadee", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-17223f38aebae018", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/graph/graphSchema.ts:125"}, "properties": {"repobilityId": "90c6aaa8dfc474c9", "scanner": "scanner-primary", "fingerprint": "17223f38aebae018", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5daf174cfa775ba1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/agent/components/ChatPanel.tsx:335"}, "properties": {"repobilityId": "d97629869b819895", "scanner": "scanner-primary", "fingerprint": "5daf174cfa775ba1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-53775e9ee21910ef", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/agent/pipeline/middleware/logging.middleware.ts:17"}, "properties": {"repobilityId": "2a5325b4ba3df405", "scanner": "scanner-primary", "fingerprint": "53775e9ee21910ef", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7c1696e669d5cb52", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/agent/skills/skill.executor.ts:135"}, "properties": {"repobilityId": "5d5fe75fb933b822", "scanner": "scanner-primary", "fingerprint": "7c1696e669d5cb52", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4c2787e7c56c4664", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/hooks/useRagSync.ts:48"}, "properties": {"repobilityId": "4df6b88fb8d34bdd", "scanner": "scanner-primary", "fingerprint": "4c2787e7c56c4664", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2f261a032a1437b1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/hooks/useGraphSync.ts:56"}, "properties": {"repobilityId": "48b000c463d360c9", "scanner": "scanner-primary", "fingerprint": "2f261a032a1437b1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e23f2c640009fc15", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/sync-cn-finance.mjs:17"}, "properties": {"repobilityId": "cecf45b7f9179992", "scanner": "scanner-primary", "fingerprint": "e23f2c640009fc15", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/sync-cn-finance.mjs"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "bd008ef80999f71a", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-6fd3a1350a723ee5", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/trade-db/package.json"}, "properties": {"repobilityId": "783e2c4ddf0ece21", "scanner": "scanner-primary", "fingerprint": "6fd3a1350a723ee5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mcp-servers/trade-db/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5c8e2a30c962195c", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/rag/package.json"}, "properties": {"repobilityId": "c4306ab80b0b9f53", "scanner": "scanner-primary", "fingerprint": "5c8e2a30c962195c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mcp-servers/rag/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fe7b0e1d1e8d21cd", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/market-data/package.json"}, "properties": {"repobilityId": "77e178f3413dd090", "scanner": "scanner-primary", "fingerprint": "fe7b0e1d1e8d21cd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mcp-servers/market-data/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7fa10159be791d8d", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: mcp-servers/memory-graph/package.json"}, "properties": {"repobilityId": "86645b9d1ce66653", "scanner": "scanner-primary", "fingerprint": "7fa10159be791d8d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mcp-servers/memory-graph/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "9ec9c93bf0d98518", "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": "aff30893e7c68b10", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "b8f8df35f5a52093", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "8c79085dadcb81d5", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "a4df69a430d0c688", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "fb71ff20ba5549e0", "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": "ff60bef1af1c28b4", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-bf3fbb2bfc8185d8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 mcp-servers/market-data/src/index.mjs:18"}, "properties": {"repobilityId": "dfe9cc2c061d93b3", "scanner": "scanner-primary", "fingerprint": "bf3fbb2bfc8185d8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5a25c321f3cdc1d5", "level": "none", "message": {"text": "Commented-code block (9 lines) in server/lib/cache.ts:6"}, "properties": {"repobilityId": "aed1475e53cf89c6", "scanner": "scanner-primary", "fingerprint": "5a25c321f3cdc1d5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-56965b1da63274d7", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/llm.ts:37"}, "properties": {"repobilityId": "0b33d942db7b66df", "scanner": "scanner-primary", "fingerprint": "56965b1da63274d7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cc34d550a4917eb8", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/services/emQuotes.ts:3"}, "properties": {"repobilityId": "82d380ec3201479c", "scanner": "scanner-primary", "fingerprint": "cc34d550a4917eb8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-46618ff4818ec134", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/webSearch.ts:27"}, "properties": {"repobilityId": "5e928df2317c1699", "scanner": "scanner-primary", "fingerprint": "46618ff4818ec134", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8a9499f2ba077f45", "level": "note", "message": {"text": "Legacy-named symbol `json_v2` in server/services/ashare.ts:338"}, "properties": {"repobilityId": "04c5ed758832ec83", "scanner": "scanner-primary", "fingerprint": "8a9499f2ba077f45", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-e435735d394fdb29", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/services/ashare.ts:912"}, "properties": {"repobilityId": "4a9614e2daee56d8", "scanner": "scanner-primary", "fingerprint": "e435735d394fdb29", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a0e887fcb81ab9e8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/ashare.ts:163"}, "properties": {"repobilityId": "834b6f166c1deab4", "scanner": "scanner-primary", "fingerprint": "a0e887fcb81ab9e8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f9f594edf4cf0070", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/services/macro.ts:65"}, "properties": {"repobilityId": "52e918c5ea59524d", "scanner": "scanner-primary", "fingerprint": "f9f594edf4cf0070", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b39f392b595dbaef", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/services/kaipanla.ts:1"}, "properties": {"repobilityId": "d872ed89258fe68e", "scanner": "scanner-primary", "fingerprint": "b39f392b595dbaef", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8b1e440b8dc6ac9a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/llmClient.ts:30"}, "properties": {"repobilityId": "88ff5213824ec5ab", "scanner": "scanner-primary", "fingerprint": "8b1e440b8dc6ac9a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f79a7d9f36ca454d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/pipeline/middleware/memory.middleware.ts:97"}, "properties": {"repobilityId": "254a9f1a17901b9a", "scanner": "scanner-primary", "fingerprint": "f79a7d9f36ca454d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e815605432d89ed0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getLimitPool.ts:25"}, "properties": {"repobilityId": "3b07d02a67a6000a", "scanner": "scanner-primary", "fingerprint": "e815605432d89ed0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e61dd54cf08a5e5c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockNews.ts:32"}, "properties": {"repobilityId": "b0c7ecc0a665834d", "scanner": "scanner-primary", "fingerprint": "e61dd54cf08a5e5c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4b6dec872c6296b4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/analyzeWithTheory.ts:45"}, "properties": {"repobilityId": "a9588b703c5ad84b", "scanner": "scanner-primary", "fingerprint": "4b6dec872c6296b4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-10c373bbe5d5462d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/hybridSearch.ts:39"}, "properties": {"repobilityId": "aa67e6b52399eb53", "scanner": "scanner-primary", "fingerprint": "10c373bbe5d5462d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-be9fcdc3d0cb5639", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getFundamentalReport.ts:46"}, "properties": {"repobilityId": "0a1ba41a45e14c82", "scanner": "scanner-primary", "fingerprint": "be9fcdc3d0cb5639", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7b4fe893f1349c50", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getMacroIndicators.ts:17"}, "properties": {"repobilityId": "375b541c56f2d0ec", "scanner": "scanner-primary", "fingerprint": "7b4fe893f1349c50", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-154efa553fb2e568", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockKline.ts:38"}, "properties": {"repobilityId": "2b43f0502fe4e8c8", "scanner": "scanner-primary", "fingerprint": "154efa553fb2e568", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4df36165c60afa8b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockFundamentals.ts:26"}, "properties": {"repobilityId": "9b8a3d3189af9ea0", "scanner": "scanner-primary", "fingerprint": "4df36165c60afa8b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3e155d012865b34b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getMarketBreadth.ts:17"}, "properties": {"repobilityId": "ab452289f0fa62ae", "scanner": "scanner-primary", "fingerprint": "3e155d012865b34b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f1c8ca2897e17984", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/semanticSearch.ts:37"}, "properties": {"repobilityId": "2ed2d40d8567ed47", "scanner": "scanner-primary", "fingerprint": "f1c8ca2897e17984", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-47779620a8bcbd87", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getIndexTrends.ts:21"}, "properties": {"repobilityId": "a7b9b7174fec57fc", "scanner": "scanner-primary", "fingerprint": "47779620a8bcbd87", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-acf6f8b32d2a821c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getNewsSummary.ts:15"}, "properties": {"repobilityId": "42ff4572cc3fe241", "scanner": "scanner-primary", "fingerprint": "acf6f8b32d2a821c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-186fa0dff0fb4fda", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/getStockQuote.ts:28"}, "properties": {"repobilityId": "5ca953c07cad4837", "scanner": "scanner-primary", "fingerprint": "186fa0dff0fb4fda", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d81fe1a064915544", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/screenStocks.ts:43"}, "properties": {"repobilityId": "11c5c3751ff171d8", "scanner": "scanner-primary", "fingerprint": "d81fe1a064915544", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e0f9a5581b8f2c66", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/agent/tools/searchWeb.ts:32"}, "properties": {"repobilityId": "82a6a00cb91facdd", "scanner": "scanner-primary", "fingerprint": "e0f9a5581b8f2c66", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9a1c82fae49cf8de", "level": "note", "message": {"text": "Legacy-named symbol `pruneOld` in src/utils/marketHistory.ts:90"}, "properties": {"repobilityId": "670d7c643205bea2", "scanner": "scanner-primary", "fingerprint": "9a1c82fae49cf8de", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-40fb2def2c927a06", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/store/persistence.ts:3"}, "properties": {"repobilityId": "8f8d11832483f73d", "scanner": "scanner-primary", "fingerprint": "40fb2def2c927a06", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-59b992d62d86a65a", "level": "note", "message": {"text": "25 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "58b9516d72ffa8ba", "scanner": "scanner-primary", "fingerprint": "59b992d62d86a65a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-342b815047f1ca0f", "level": "note", "message": {"text": "Unused endpoint: GET /api/mcp/rag/status"}, "properties": {"repobilityId": "bd55898c31df3ef0", "scanner": "scanner-primary", "fingerprint": "342b815047f1ca0f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-28ea84cdf44b8b63", "level": "note", "message": {"text": "Unused endpoint: GET /api/mcp/graph/stats"}, "properties": {"repobilityId": "66c00441aa1337c2", "scanner": "scanner-primary", "fingerprint": "28ea84cdf44b8b63", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1cb805b41f26da35", "level": "note", "message": {"text": "Unused endpoint: PUT /api/memory/:userId"}, "properties": {"repobilityId": "a176b8ad812de23f", "scanner": "scanner-primary", "fingerprint": "1cb805b41f26da35", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1198dec5ef131620", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/memory/:userId/profile"}, "properties": {"repobilityId": "a32827c0089ec01e", "scanner": "scanner-primary", "fingerprint": "1198dec5ef131620", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ab314172fb2a6b26", "level": "note", "message": {"text": "Unused endpoint: POST /api/memory/:userId/plans"}, "properties": {"repobilityId": "aac274fae8ede5d5", "scanner": "scanner-primary", "fingerprint": "ab314172fb2a6b26", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d37efb71b70bc6ad", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/memory/:userId/plans/:planId"}, "properties": {"repobilityId": "e8e3382fc69872fb", "scanner": "scanner-primary", "fingerprint": "d37efb71b70bc6ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-191b4cd103025c12", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/memory/:userId/market"}, "properties": {"repobilityId": "12d7a89327d719bb", "scanner": "scanner-primary", "fingerprint": "191b4cd103025c12", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f42094d323d603da", "level": "note", "message": {"text": "Unused endpoint: GET /api/memory-enhanced/:userId"}, "properties": {"repobilityId": "2e4b22107dd7f51e", "scanner": "scanner-primary", "fingerprint": "f42094d323d603da", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-08da66f43edce44d", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/memory-enhanced/:userId/profile"}, "properties": {"repobilityId": "559d93e701745982", "scanner": "scanner-primary", "fingerprint": "08da66f43edce44d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-832932bca23a0bf4", "level": "note", "message": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/infer-profile"}, "properties": {"repobilityId": "c4dc9a492fdf30dd", "scanner": "scanner-primary", "fingerprint": "832932bca23a0bf4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-53ccda2c2fe41011", "level": "note", "message": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/lessons"}, "properties": {"repobilityId": "76573e2b00b85e6f", "scanner": "scanner-primary", "fingerprint": "53ccda2c2fe41011", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca80634db75d594d", "level": "note", "message": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/patterns"}, "properties": {"repobilityId": "c3803a8a5c96fffd", "scanner": "scanner-primary", "fingerprint": "ca80634db75d594d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac0e711d2cb3828f", "level": "note", "message": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/decisions"}, "properties": {"repobilityId": "a497372cec904b52", "scanner": "scanner-primary", "fingerprint": "ac0e711d2cb3828f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-da745a358147aece", "level": "note", "message": {"text": "Unused endpoint: POST /api/memory-enhanced/:userId/actions"}, "properties": {"repobilityId": "b2e52ea6c9b5b985", "scanner": "scanner-primary", "fingerprint": "da745a358147aece", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1aa9cc6b4dfed331", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/memory-enhanced/:userId/actions/:actionId"}, "properties": {"repobilityId": "be8ae5a211274614", "scanner": "scanner-primary", "fingerprint": "1aa9cc6b4dfed331", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a4bf36abff244783", "level": "note", "message": {"text": "Unused endpoint: POST /api/agent/chat"}, "properties": {"repobilityId": "82cdd2370e52bb49", "scanner": "scanner-primary", "fingerprint": "a4bf36abff244783", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9802182873141fdb", "level": "note", "message": {"text": "Unused endpoint: GET /api/db/trades"}, "properties": {"repobilityId": "343081865eb890eb", "scanner": "scanner-primary", "fingerprint": "9802182873141fdb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-114349b996b8c38e", "level": "note", "message": {"text": "Unused endpoint: POST /api/db/trades"}, "properties": {"repobilityId": "63775a4065fbc9a0", "scanner": "scanner-primary", "fingerprint": "114349b996b8c38e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-027eceb0fb349027", "level": "note", "message": {"text": "Unused endpoint: GET /api/db/trade-groups"}, "properties": {"repobilityId": "dc4a3943d2ae37d8", "scanner": "scanner-primary", "fingerprint": "027eceb0fb349027", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e1eaa47c801455cf", "level": "note", "message": {"text": "Unused endpoint: POST /api/db/trade-groups"}, "properties": {"repobilityId": "6199d847010ceb9b", "scanner": "scanner-primary", "fingerprint": "e1eaa47c801455cf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d4c10d6e56e69ad", "level": "note", "message": {"text": "Unused endpoint: GET /api/db/review-notes/:groupId"}, "properties": {"repobilityId": "3721268a40dfc882", "scanner": "scanner-primary", "fingerprint": "4d4c10d6e56e69ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd5edcfc2b3add79", "level": "note", "message": {"text": "Unused endpoint: PUT /api/db/review-notes/:groupId"}, "properties": {"repobilityId": "d4df485e3a0bbc10", "scanner": "scanner-primary", "fingerprint": "cd5edcfc2b3add79", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1c2bf402aeaa2f3c", "level": "note", "message": {"text": "Unused endpoint: POST /api/db/import-batches"}, "properties": {"repobilityId": "b6d596a58f1c4193", "scanner": "scanner-primary", "fingerprint": "1c2bf402aeaa2f3c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8d667555e0c8f80d", "level": "note", "message": {"text": "Unused endpoint: GET /api/ashare"}, "properties": {"repobilityId": "1f42cf11d2424732", "scanner": "scanner-primary", "fingerprint": "8d667555e0c8f80d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7ef95d4e9930e8fe", "level": "note", "message": {"text": "Unused endpoint: GET /api/hk"}, "properties": {"repobilityId": "b8aed26609525fb4", "scanner": "scanner-primary", "fingerprint": "7ef95d4e9930e8fe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7fd3224443b63cdb", "level": "note", "message": {"text": "Unused endpoint: GET /api/hk/quote"}, "properties": {"repobilityId": "a6201dddedfc1c85", "scanner": "scanner-primary", "fingerprint": "7fd3224443b63cdb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-272e31e77f705acb", "level": "note", "message": {"text": "Unused endpoint: GET /api/us"}, "properties": {"repobilityId": "4519e6de33714ee1", "scanner": "scanner-primary", "fingerprint": "272e31e77f705acb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-39eb0c8fa833690a", "level": "note", "message": {"text": "Unused endpoint: GET /api/us/quote"}, "properties": {"repobilityId": "9e1b8af1fc7f5403", "scanner": "scanner-primary", "fingerprint": "39eb0c8fa833690a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bb7804b1661d7dbf", "level": "note", "message": {"text": "Unused endpoint: GET /api/hotlist"}, "properties": {"repobilityId": "4e383054987a04a6", "scanner": "scanner-primary", "fingerprint": "bb7804b1661d7dbf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8b5061676d4813b8", "level": "note", "message": {"text": "Unused endpoint: GET /api/highs"}, "properties": {"repobilityId": "9fc3f4d149ee45f1", "scanner": "scanner-primary", "fingerprint": "8b5061676d4813b8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bd9ca55dfdc250fc", "level": "note", "message": {"text": "Unused endpoint: GET /api/sentiment"}, "properties": {"repobilityId": "2d4787f62015f5ad", "scanner": "scanner-primary", "fingerprint": "bd9ca55dfdc250fc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}