{"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-32ab1ee49a2b9d26", "name": "Possibly dead Python function: emit", "shortDescription": {"text": "Possibly dead Python function: emit"}, "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-972fa222ed524c4c", "name": "Possibly dead Python function: calculate_cagr", "shortDescription": {"text": "Possibly dead Python function: calculate_cagr"}, "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-ef5bb61f09262641", "name": "Stray `console.log` in TS/JS \u2014 scripts/test_csv.js:65", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test_csv.js:65"}, "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-20d1b35cff179b8d", "name": "`truncate` class without `title=` for hover reveal \u2014 components/FilterSidebar.tsx:280", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/FilterSidebar.tsx:280"}, "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-3145aedc18cba8c0", "name": "`truncate` class without `title=` for hover reveal \u2014 components/CockpitDashboard.tsx:822", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/CockpitDashboard.tsx:822"}, "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-a3ee4f2ddec17d1c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/YoutubeStrategyDashboard.tsx:358", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/YoutubeStrategyDashboard.tsx:358"}, "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-17688a166fa7c44c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/StockDetailModal.tsx:211", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/StockDetailModal.tsx:211"}, "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-1a0383bfd54cc846", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ScreenerDashboard.tsx:1046", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ScreenerDashboard.tsx:1046"}, "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-5346e3e70cef22de", "name": "Stray `console.log` in TS/JS \u2014 components/ScreenerDashboard.tsx:306", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 components/ScreenerDashboard.tsx:306"}, "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-93bb1b049bc8423d", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ReportsDashboard.tsx:631", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ReportsDashboard.tsx:631"}, "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-b44e08b5b67e9eef", "name": "`truncate` class without `title=` for hover reveal \u2014 components/LanguageToggle.tsx:73", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/LanguageToggle.tsx:73"}, "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-6cea999b9099ba58", "name": "`truncate` class without `title=` for hover reveal \u2014 components/StockCard.tsx:85", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/StockCard.tsx:85"}, "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-736aaab981621359", "name": "Stray `console.log` in TS/JS \u2014 app/api/analysis/route.ts:60", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/api/analysis/route.ts:60"}, "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-cc8d03a255f36b18", "name": "Insecure pattern 'tls_verify_false' in scripts/fetch_data_intl.py:47", "shortDescription": {"text": "Insecure pattern 'tls_verify_false' in scripts/fetch_data_intl.py:47"}, "fullDescription": {"text": "Found a known-risky pattern (tls_verify_false). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-855f586fd8595fcc", "name": "Insecure pattern 'tls_verify_false' in scripts/fetch_taiwan.py:33", "shortDescription": {"text": "Insecure pattern 'tls_verify_false' in scripts/fetch_taiwan.py:33"}, "fullDescription": {"text": "Found a known-risky pattern (tls_verify_false). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8b76745f3272fc47", "name": "Insecure pattern 'node_child_process' in app/api/live-prices/route.ts:2", "shortDescription": {"text": "Insecure pattern 'node_child_process' in app/api/live-prices/route.ts:2"}, "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-65ca15295a4fe0b2", "name": "Insecure pattern 'node_child_process' in app/api/generate-prompt/route.ts:2", "shortDescription": {"text": "Insecure pattern 'node_child_process' in app/api/generate-prompt/route.ts:2"}, "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-c9e016f5ad1c0775", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@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-ae54e664eaae2efa", "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-a0fad8ba12240eb1", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@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-2e38bfaa186346d7", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@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-e0a509c8391b537c", "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-1ebe5de28fcf5287", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@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-1eb8d23c99ee359f", "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-4e27d75ce041fe15", "name": "Very large file: scripts/score_paradigm.py (1571 lines)", "shortDescription": {"text": "Very large file: scripts/score_paradigm.py (1571 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a188b8aa53ac530f", "name": "Very large file: scripts/score_reverse.py (2479 lines)", "shortDescription": {"text": "Very large file: scripts/score_reverse.py (2479 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-61825721ad67b741", "name": "Very large file: components/CockpitDashboard.tsx (1286 lines)", "shortDescription": {"text": "Very large file: components/CockpitDashboard.tsx (1286 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ed56e8120297da2f", "name": "Very large file: components/StockDetailModal.tsx (940 lines)", "shortDescription": {"text": "Very large file: components/StockDetailModal.tsx (940 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-26f20cb552cc21b5", "name": "Very large file: components/ScreenerDashboard.tsx (2525 lines)", "shortDescription": {"text": "Very large file: components/ScreenerDashboard.tsx (2525 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-171c7d8d26284240", "name": "Very large file: components/ReportsDashboard.tsx (957 lines)", "shortDescription": {"text": "Very large file: components/ReportsDashboard.tsx (957 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "5 test file(s) for 89 source file(s) (ratio 0.06). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "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-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 540 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 18 placeholder/mock markers across 11 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-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bc4806ad359434d8", "name": "Legacy-named symbol `factor_lab_v1` in scripts/run_chain.py:215", "shortDescription": {"text": "Legacy-named symbol `factor_lab_v1` in scripts/run_chain.py:215"}, "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-f47e0ded0b03d2a6", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/run_chain.py:58", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/run_chain.py:58"}, "fullDescription": {"text": "`subprocess.run(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bffffa9b53f02607", "name": "Commented-code block (5 lines) in scripts/build_fundamentals_history.py:277", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/build_fundamentals_history.py:277"}, "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-1efd07bebf237a21", "name": "Commented-code block (5 lines) in scripts/build_portfolio_plan.py:137", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/build_portfolio_plan.py:137"}, "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-1912f77d4711c3e0", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/fetch_sec_data.py:22", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/fetch_sec_data.py:22"}, "fullDescription": {"text": "`requests.get(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-79a567213df28de8", "name": "Legacy-named symbol `p_old` in scripts/score_paradigm.py:458", "shortDescription": {"text": "Legacy-named symbol `p_old` in scripts/score_paradigm.py:458"}, "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-4ad0ff882687b751", "name": "Commented-code block (5 lines) in scripts/score_paradigm.py:1103", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/score_paradigm.py:1103"}, "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-de1d2f7716afa873", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/show_examples.py:9", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/show_examples.py:9"}, "fullDescription": {"text": "`subprocess.check_output(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a6d7bbe55ebfd436", "name": "Legacy-named symbol `myPortfolio_v1` in components/CockpitDashboard.tsx:305", "shortDescription": {"text": "Legacy-named symbol `myPortfolio_v1` in components/CockpitDashboard.tsx:305"}, "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-1957ae6f848d2727", "name": "Commented-code block (5 lines) in components/ScreenerDashboard.tsx:702", "shortDescription": {"text": "Commented-code block (5 lines) in components/ScreenerDashboard.tsx:702"}, "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-7d9f652f2091df63", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/prompt-builder.ts:347", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/prompt-builder.ts:347"}, "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-3afeb9908ad4421c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/data-service.ts:224", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/data-service.ts:224"}, "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-ebf90c1b38f32134", "name": "Network/subprocess call without timeout or try/except \u2014 scratch/wipe_reports.py:22", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/wipe_reports.py:22"}, "fullDescription": {"text": "`requests.delete(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7c47aa099fe75486", "name": "Network/subprocess call without timeout or try/except \u2014 scratch/check_queue.py:10", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/check_queue.py:10"}, "fullDescription": {"text": "`requests.get(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d3fbbf6a0742d74", "name": "Legacy-named symbol `copy_to_clipboard_old` in scratch/update_dashboard.py:14", "shortDescription": {"text": "Legacy-named symbol `copy_to_clipboard_old` in scratch/update_dashboard.py:14"}, "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-9fc29c250f78e721", "name": "Network/subprocess call without timeout or try/except \u2014 scratch/reset_ttwo.py:26", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/reset_ttwo.py:26"}, "fullDescription": {"text": "`requests.patch(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3cd5578236cca362", "name": "Network/subprocess call without timeout or try/except \u2014 scratch/manual_worker.py:23", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/manual_worker.py:23"}, "fullDescription": {"text": "`requests.get(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c3fdf91740cf8deb", "name": "Legacy-named symbol `ui_old` in scratch/add_buttons_modal.py:34", "shortDescription": {"text": "Legacy-named symbol `ui_old` in scratch/add_buttons_modal.py:34"}, "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-fffb2db626826a72", "name": "Network/subprocess call without timeout or try/except \u2014 scratch/check_token_usage.py:21", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/check_token_usage.py:21"}, "fullDescription": {"text": "`requests.get(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-13c21a48a5443d78", "name": "Network/subprocess call without timeout or try/except \u2014 scratch/bulk_reset.py:27", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/bulk_reset.py:27"}, "fullDescription": {"text": "`requests.patch(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-33abb3dd0471bf87", "name": "Legacy-named symbol `run_old` in scratch/update_toast_and_polling.py:15", "shortDescription": {"text": "Legacy-named symbol `run_old` in scratch/update_toast_and_polling.py:15"}, "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-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nscripts/fetch_analyst_coverage.py:load_json, scripts/enrich_missing_sectors.py:load_json, scripts/fetch_eps_trajectory.py:load_json\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-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:\nscripts/fetch_phase2_screener.py:safe_get_df, scripts/fetch_data.py:safe_get_df\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-0027e313ade46c8f", "name": "Near-duplicate function bodies in 7 places", "shortDescription": {"text": "Near-duplicate function bodies in 7 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nscripts/score_unified.py:load_json, scripts/stress_scenario.py:load, scripts/build_portfolio_plan.py:load_json, scripts/fetch_overlay_signals.py:load_json\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}}]}}, "automationDetails": {"id": "repobility/18187"}, "properties": {"repository": "riperdy-tech/stock-screener", "repoUrl": "https://github.com/riperdy-tech/stock-screener", "branch": "main"}, "results": [{"ruleId": "scanner-32ab1ee49a2b9d26", "level": "note", "message": {"text": "Possibly dead Python function: emit"}, "properties": {"repobilityId": "fecc700ec874b669", "scanner": "scanner-primary", "fingerprint": "32ab1ee49a2b9d26", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/fetch_data.py:44"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-972fa222ed524c4c", "level": "note", "message": {"text": "Possibly dead Python function: calculate_cagr"}, "properties": {"repobilityId": "0c05ddb8087ee70c", "scanner": "scanner-primary", "fingerprint": "972fa222ed524c4c", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/fetch_data.py:126"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ef5bb61f09262641", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test_csv.js:65"}, "properties": {"repobilityId": "19cfaccea0097ab5", "scanner": "scanner-primary", "fingerprint": "ef5bb61f09262641", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-20d1b35cff179b8d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/FilterSidebar.tsx:280"}, "properties": {"repobilityId": "634246ed1807575e", "scanner": "scanner-primary", "fingerprint": "20d1b35cff179b8d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3145aedc18cba8c0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/CockpitDashboard.tsx:822"}, "properties": {"repobilityId": "c2f0073890932a23", "scanner": "scanner-primary", "fingerprint": "3145aedc18cba8c0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a3ee4f2ddec17d1c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/YoutubeStrategyDashboard.tsx:358"}, "properties": {"repobilityId": "eb674ad62cf5a100", "scanner": "scanner-primary", "fingerprint": "a3ee4f2ddec17d1c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-17688a166fa7c44c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/StockDetailModal.tsx:211"}, "properties": {"repobilityId": "7a6960fa16e5c0bd", "scanner": "scanner-primary", "fingerprint": "17688a166fa7c44c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1a0383bfd54cc846", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ScreenerDashboard.tsx:1046"}, "properties": {"repobilityId": "985a7c54387ebdbe", "scanner": "scanner-primary", "fingerprint": "1a0383bfd54cc846", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5346e3e70cef22de", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 components/ScreenerDashboard.tsx:306"}, "properties": {"repobilityId": "2f2969ac98fecd6e", "scanner": "scanner-primary", "fingerprint": "5346e3e70cef22de", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-93bb1b049bc8423d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ReportsDashboard.tsx:631"}, "properties": {"repobilityId": "fb1d36058d2ff509", "scanner": "scanner-primary", "fingerprint": "93bb1b049bc8423d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b44e08b5b67e9eef", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/LanguageToggle.tsx:73"}, "properties": {"repobilityId": "da1b5933ef0def4e", "scanner": "scanner-primary", "fingerprint": "b44e08b5b67e9eef", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6cea999b9099ba58", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/StockCard.tsx:85"}, "properties": {"repobilityId": "4c430b2e5a6799e9", "scanner": "scanner-primary", "fingerprint": "6cea999b9099ba58", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-736aaab981621359", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/api/analysis/route.ts:60"}, "properties": {"repobilityId": "13c2c4e16317b254", "scanner": "scanner-primary", "fingerprint": "736aaab981621359", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cc8d03a255f36b18", "level": "error", "message": {"text": "Insecure pattern 'tls_verify_false' in scripts/fetch_data_intl.py:47"}, "properties": {"repobilityId": "a58df4f7bc22662c", "scanner": "scanner-primary", "fingerprint": "cc8d03a255f36b18", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "tls_verify_false"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/fetch_data_intl.py"}, "region": {"startLine": 47}}}]}, {"ruleId": "scanner-855f586fd8595fcc", "level": "error", "message": {"text": "Insecure pattern 'tls_verify_false' in scripts/fetch_taiwan.py:33"}, "properties": {"repobilityId": "0fec90d4ee88136b", "scanner": "scanner-primary", "fingerprint": "855f586fd8595fcc", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "tls_verify_false"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/fetch_taiwan.py"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-8b76745f3272fc47", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in app/api/live-prices/route.ts:2"}, "properties": {"repobilityId": "e6c4be306fcaf87f", "scanner": "scanner-primary", "fingerprint": "8b76745f3272fc47", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/api/live-prices/route.ts"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-65ca15295a4fe0b2", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in app/api/generate-prompt/route.ts:2"}, "properties": {"repobilityId": "945a2e3e6ee70d44", "scanner": "scanner-primary", "fingerprint": "65ca15295a4fe0b2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/api/generate-prompt/route.ts"}, "region": {"startLine": 2}}}]}, {"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-c9e016f5ad1c0775", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "415a384941cc8ef7", "scanner": "scanner-primary", "fingerprint": "c9e016f5ad1c0775", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/schedule-data-fetch.yml"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-c9e016f5ad1c0775", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "3005f1c916663d92", "scanner": "scanner-primary", "fingerprint": "c9e016f5ad1c0775", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/schedule-data-fetch.yml"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-ae54e664eaae2efa", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "476a3721a82eb28e", "scanner": "scanner-primary", "fingerprint": "ae54e664eaae2efa", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/schedule-data-fetch.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a0fad8ba12240eb1", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "cde5e7372e77ee0a", "scanner": "scanner-primary", "fingerprint": "a0fad8ba12240eb1", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ai-worker.yml"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-a0fad8ba12240eb1", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "3bf67148e75c9c70", "scanner": "scanner-primary", "fingerprint": "a0fad8ba12240eb1", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ai-worker.yml"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-2e38bfaa186346d7", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9e5724d285300763", "scanner": "scanner-primary", "fingerprint": "2e38bfaa186346d7", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/paradigm-weekly-analyst.yml"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-2e38bfaa186346d7", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e20077f476b7be99", "scanner": "scanner-primary", "fingerprint": "2e38bfaa186346d7", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/paradigm-weekly-analyst.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-e0a509c8391b537c", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "b34116edc0eb6d86", "scanner": "scanner-primary", "fingerprint": "e0a509c8391b537c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/paradigm-weekly-analyst.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1ebe5de28fcf5287", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "0a702992ddd939b8", "scanner": "scanner-primary", "fingerprint": "1ebe5de28fcf5287", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/factor-recalibration.yml"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-1ebe5de28fcf5287", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a9de4271ef1888b6", "scanner": "scanner-primary", "fingerprint": "1ebe5de28fcf5287", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/factor-recalibration.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "scanner-1eb8d23c99ee359f", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "62b489623b54ff81", "scanner": "scanner-primary", "fingerprint": "1eb8d23c99ee359f", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/factor-recalibration.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4e27d75ce041fe15", "level": "note", "message": {"text": "Very large file: scripts/score_paradigm.py (1571 lines)"}, "properties": {"repobilityId": "8a23db784135cd7a", "scanner": "scanner-primary", "fingerprint": "4e27d75ce041fe15", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-a188b8aa53ac530f", "level": "note", "message": {"text": "Very large file: scripts/score_reverse.py (2479 lines)"}, "properties": {"repobilityId": "973ef206f959114a", "scanner": "scanner-primary", "fingerprint": "a188b8aa53ac530f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-61825721ad67b741", "level": "note", "message": {"text": "Very large file: components/CockpitDashboard.tsx (1286 lines)"}, "properties": {"repobilityId": "b08e16c6e4af9715", "scanner": "scanner-primary", "fingerprint": "61825721ad67b741", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ed56e8120297da2f", "level": "note", "message": {"text": "Very large file: components/StockDetailModal.tsx (940 lines)"}, "properties": {"repobilityId": "321b2242a8d6c418", "scanner": "scanner-primary", "fingerprint": "ed56e8120297da2f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-26f20cb552cc21b5", "level": "note", "message": {"text": "Very large file: components/ScreenerDashboard.tsx (2525 lines)"}, "properties": {"repobilityId": "e1f0b6687c722067", "scanner": "scanner-primary", "fingerprint": "26f20cb552cc21b5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-171c7d8d26284240", "level": "note", "message": {"text": "Very large file: components/ReportsDashboard.tsx (957 lines)"}, "properties": {"repobilityId": "729300a5bd0adb6e", "scanner": "scanner-primary", "fingerprint": "171c7d8d26284240", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "fe71221c25a50ce3", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "81b29f9ca55ba70d", "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": "8ba28957a0cd3c75", "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": "470b8d70312dc0b4", "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": "edf25447f15f3e4a", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "2e5bf18988620417", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "50a24881df51290e", "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": "f227f0ef9a7fd9aa", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-bc4806ad359434d8", "level": "note", "message": {"text": "Legacy-named symbol `factor_lab_v1` in scripts/run_chain.py:215"}, "properties": {"repobilityId": "1f9662f0298f1c4c", "scanner": "scanner-primary", "fingerprint": "bc4806ad359434d8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f47e0ded0b03d2a6", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/run_chain.py:58"}, "properties": {"repobilityId": "1cd16abda6da13c5", "scanner": "scanner-primary", "fingerprint": "f47e0ded0b03d2a6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bffffa9b53f02607", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/build_fundamentals_history.py:277"}, "properties": {"repobilityId": "422611ee3d7a26ce", "scanner": "scanner-primary", "fingerprint": "bffffa9b53f02607", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1efd07bebf237a21", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/build_portfolio_plan.py:137"}, "properties": {"repobilityId": "730b7c6253aefec4", "scanner": "scanner-primary", "fingerprint": "1efd07bebf237a21", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1912f77d4711c3e0", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/fetch_sec_data.py:22"}, "properties": {"repobilityId": "8f91892ada059d08", "scanner": "scanner-primary", "fingerprint": "1912f77d4711c3e0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-79a567213df28de8", "level": "note", "message": {"text": "Legacy-named symbol `p_old` in scripts/score_paradigm.py:458"}, "properties": {"repobilityId": "56f5ee9a3c922a7b", "scanner": "scanner-primary", "fingerprint": "79a567213df28de8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-4ad0ff882687b751", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/score_paradigm.py:1103"}, "properties": {"repobilityId": "01fe37bd74b5bfe6", "scanner": "scanner-primary", "fingerprint": "4ad0ff882687b751", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-de1d2f7716afa873", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/show_examples.py:9"}, "properties": {"repobilityId": "d67b0d410a54f60a", "scanner": "scanner-primary", "fingerprint": "de1d2f7716afa873", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a6d7bbe55ebfd436", "level": "note", "message": {"text": "Legacy-named symbol `myPortfolio_v1` in components/CockpitDashboard.tsx:305"}, "properties": {"repobilityId": "c4ff5cbcb6bd0b1a", "scanner": "scanner-primary", "fingerprint": "a6d7bbe55ebfd436", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1957ae6f848d2727", "level": "none", "message": {"text": "Commented-code block (5 lines) in components/ScreenerDashboard.tsx:702"}, "properties": {"repobilityId": "ed18dca1249e6719", "scanner": "scanner-primary", "fingerprint": "1957ae6f848d2727", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7d9f652f2091df63", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/prompt-builder.ts:347"}, "properties": {"repobilityId": "c520b3b876b5026f", "scanner": "scanner-primary", "fingerprint": "7d9f652f2091df63", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3afeb9908ad4421c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/data-service.ts:224"}, "properties": {"repobilityId": "ddd8fae25d49be87", "scanner": "scanner-primary", "fingerprint": "3afeb9908ad4421c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ebf90c1b38f32134", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/wipe_reports.py:22"}, "properties": {"repobilityId": "0f85b2a1bd4dd2ac", "scanner": "scanner-primary", "fingerprint": "ebf90c1b38f32134", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7c47aa099fe75486", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/check_queue.py:10"}, "properties": {"repobilityId": "84570df586be5626", "scanner": "scanner-primary", "fingerprint": "7c47aa099fe75486", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2d3fbbf6a0742d74", "level": "note", "message": {"text": "Legacy-named symbol `copy_to_clipboard_old` in scratch/update_dashboard.py:14"}, "properties": {"repobilityId": "3cf66dfd7ae02ea0", "scanner": "scanner-primary", "fingerprint": "2d3fbbf6a0742d74", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-9fc29c250f78e721", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/reset_ttwo.py:26"}, "properties": {"repobilityId": "c3d8b8d7b9604b8e", "scanner": "scanner-primary", "fingerprint": "9fc29c250f78e721", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3cd5578236cca362", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/manual_worker.py:23"}, "properties": {"repobilityId": "5e981e859edf0b74", "scanner": "scanner-primary", "fingerprint": "3cd5578236cca362", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c3fdf91740cf8deb", "level": "note", "message": {"text": "Legacy-named symbol `ui_old` in scratch/add_buttons_modal.py:34"}, "properties": {"repobilityId": "24bb57e012eab066", "scanner": "scanner-primary", "fingerprint": "c3fdf91740cf8deb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-fffb2db626826a72", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/check_token_usage.py:21"}, "properties": {"repobilityId": "c13d71dc9efe9fc1", "scanner": "scanner-primary", "fingerprint": "fffb2db626826a72", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-13c21a48a5443d78", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scratch/bulk_reset.py:27"}, "properties": {"repobilityId": "e48fa49e0e63b2dc", "scanner": "scanner-primary", "fingerprint": "13c21a48a5443d78", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-33abb3dd0471bf87", "level": "note", "message": {"text": "Legacy-named symbol `run_old` in scratch/update_toast_and_polling.py:15"}, "properties": {"repobilityId": "908aaf0f3bb6456a", "scanner": "scanner-primary", "fingerprint": "33abb3dd0471bf87", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "b813ec26b0dc4bf9", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "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": "4a8d8f1b42937b33", "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": "96da273fb4c2d1ef", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-0027e313ade46c8f", "level": "note", "message": {"text": "Near-duplicate function bodies in 7 places"}, "properties": {"repobilityId": "38299a4ad6a7399e", "scanner": "scanner-primary", "fingerprint": "0027e313ade46c8f", "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": "44d6268e697f1c46", "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": "892dfbcf95a3ea36", "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": "9e8c1ad55ba448a0", "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": "55285013ccb46997", "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": "de7c0487f2187053", "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": "be1ca4cb8b206243", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}]}]}