{"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-af9640d94356191e", "name": "Possibly dead Python function: validate_proposal", "shortDescription": {"text": "Possibly dead Python function: validate_proposal"}, "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-42b94adf4d67e3a8", "name": "Possibly dead Python function: assemble_entry_input", "shortDescription": {"text": "Possibly dead Python function: assemble_entry_input"}, "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-f4580bef2cffb14f", "name": "Possibly dead Python function: confirm_command", "shortDescription": {"text": "Possibly dead Python function: confirm_command"}, "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-d96fc967edc01b92", "name": "Possibly dead Python function: evaluate_exits", "shortDescription": {"text": "Possibly dead Python function: evaluate_exits"}, "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-3ea916f1acb850dc", "name": "Possibly dead Python function: review_cmd", "shortDescription": {"text": "Possibly dead Python function: review_cmd"}, "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-ddf445f924a72610", "name": "Possibly dead Python function: decorator", "shortDescription": {"text": "Possibly dead Python function: decorator"}, "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-c89eae4f16d49318", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/components/layout.tsx:141", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/components/layout.tsx:141"}, "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-ef602aac78a98e19", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/ChatSessionPage.tsx:399", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/ChatSessionPage.tsx:399"}, "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-d31d31734e3898ed", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/ReviewDetailPage.tsx:211", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/ReviewDetailPage.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-00f27064fac81501", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/PaperOverviewPage.tsx:127", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/PaperOverviewPage.tsx:127"}, "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-9aaeadee3fa8909c", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 web-admin/src/pages/SessionsPage.tsx:34", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 web-admin/src/pages/SessionsPage.tsx:34"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d5ef3bc5aeb372b0", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/MarketPage.tsx:246", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/MarketPage.tsx:246"}, "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-eef88486e9d0d268", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/AuditPage.tsx:157", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/AuditPage.tsx:157"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-28808fc4d6bb9721", "name": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/DashboardPage.tsx:221", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/DashboardPage.tsx:221"}, "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-5292ed8116f6d043", "name": "Insecure pattern 'node_child_process' in web-admin/e2e/global-setup.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in web-admin/e2e/global-setup.ts:1"}, "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-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a949d199616af067", "name": "Node manifest has dependencies but no lockfile: web-admin/e2e/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: web-admin/e2e/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 19 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 54 placeholder/mock markers across 23 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: ci, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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 ci, lockfile. 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-10be1b379989d3a6", "name": "Agent authority lacks a verifier contract: .claude/rules/capability-map.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/rules/capability-map.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8e1c592f3726c637", "name": "Agent authority lacks a verifier contract: .claude/rules/ssot-pointers.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/rules/ssot-pointers.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-df8d7aecf447de62", "name": "Agent authority lacks a verifier contract: .claude/commands/opsx/archive.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/commands/opsx/archive.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-021b572fe2fa6b9c", "name": "Agent authority lacks a verifier contract: .claude/commands/opsx/apply.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/commands/opsx/apply.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-14b94de34d897ad4", "name": "Agent authority lacks a verifier contract: .claude/skills/openspec-apply-change/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/openspec-apply-change/SKILL.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8a585f74bb40a5f1", "name": "Agent authority lacks a verifier contract: .claude/skills/openspec-archive-change/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/openspec-archive-change/SKILL.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-63d623eb7d1828ef", "name": "Legacy-named symbol `dec_old` in tests/test_live_journal_provider.py:206", "shortDescription": {"text": "Legacy-named symbol `dec_old` in tests/test_live_journal_provider.py:206"}, "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-deed588c64acd74d", "name": "Legacy-named symbol `dec_old` in tests/test_confirm_gate.py:552", "shortDescription": {"text": "Legacy-named symbol `dec_old` in tests/test_confirm_gate.py:552"}, "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-923f56b3bab27a24", "name": "Legacy-named symbol `test_serialize_payload_is_same_reference_no_deep_copy` in tests/test_admin_event_serializer.py:45", "shortDescription": {"text": "Legacy-named symbol `test_serialize_payload_is_same_reference_no_deep_copy` in tests/test_admin_event_serializer.py:45"}, "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-f9ea29896c194ee2", "name": "Legacy-named symbol `model_copy` in tests/test_input_assembler_snapshot.py:219", "shortDescription": {"text": "Legacy-named symbol `model_copy` in tests/test_input_assembler_snapshot.py:219"}, "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-2d0e42a1ef0eacda", "name": "Commented-code block (5 lines) in tests/test_decider_orchestrator.py:226", "shortDescription": {"text": "Commented-code block (5 lines) in tests/test_decider_orchestrator.py:226"}, "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-307af0aa460b5a37", "name": "Legacy-named symbol `model_copy` in tests/test_decider_validator.py:127", "shortDescription": {"text": "Legacy-named symbol `model_copy` in tests/test_decider_validator.py:127"}, "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-a2225470d15d3bef", "name": "Legacy-named symbol `model_copy` in tests/proposal/test_round_trip.py:86", "shortDescription": {"text": "Legacy-named symbol `model_copy` in tests/proposal/test_round_trip.py:86"}, "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-90d6f4d264293511", "name": "Commented-code block (5 lines) in web-admin/src/lib/journal-kinds.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in web-admin/src/lib/journal-kinds.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-f6f1c76871139855", "name": "Commented-code block (5 lines) in web-admin/e2e/playwright.config.ts:14", "shortDescription": {"text": "Commented-code block (5 lines) in web-admin/e2e/playwright.config.ts:14"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5a3daf2b01dbf794", "name": "Commented-code block (5 lines) in web-admin/e2e/constants.ts:4", "shortDescription": {"text": "Commented-code block (5 lines) in web-admin/e2e/constants.ts:4"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-166bf66572562fad", "name": "Network/subprocess call without timeout or try/except \u2014 web-public/scripts/fetch_pixellab_sheets.py:52", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 web-public/scripts/fetch_pixellab_sheets.py:52"}, "fullDescription": {"text": "`urllib.request.urlopen(...)` 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-66870dab2c888195", "name": "Legacy-named symbol `future_unknown_v2` in web-public/src/__tests__/usePublicSSE.test.tsx:77", "shortDescription": {"text": "Legacy-named symbol `future_unknown_v2` in web-public/src/__tests__/usePublicSSE.test.tsx:77"}, "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-a84194d0724415d3", "name": "Legacy-named symbol `future_unknown_v2` in web-public/src/__tests__/eventToAction.test.ts:84", "shortDescription": {"text": "Legacy-named symbol `future_unknown_v2` in web-public/src/__tests__/eventToAction.test.ts:84"}, "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-0f80c33e68b0a6bc", "name": "Commented-code block (8 lines) in src/ohmystock/config.py:93", "shortDescription": {"text": "Commented-code block (8 lines) in src/ohmystock/config.py:93"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b654fb49cdbbacec", "name": "Legacy-named symbol `_migrate_kind_check_if_legacy` in src/ohmystock/journal/schema.py:131", "shortDescription": {"text": "Legacy-named symbol `_migrate_kind_check_if_legacy` in src/ohmystock/journal/schema.py:131"}, "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-72e208dc2b8f8b2b", "name": "Commented-code block (5 lines) in src/ohmystock/api/db.py:48", "shortDescription": {"text": "Commented-code block (5 lines) in src/ohmystock/api/db.py:48"}, "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-b6f4c06ae5805b60", "name": "Commented-code block (5 lines) in src/ohmystock/api/routes/proposals.py:80", "shortDescription": {"text": "Commented-code block (5 lines) in src/ohmystock/api/routes/proposals.py:80"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-955725fdfc53d6db", "name": "Legacy-named symbol `model_copy` in src/ohmystock/decider/validator.py:72", "shortDescription": {"text": "Legacy-named symbol `model_copy` in src/ohmystock/decider/validator.py:72"}, "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-8e047ab7af03962f", "name": "7 env vars used in code but missing from .env.example", "shortDescription": {"text": "7 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ANALYZE`, `CI`, `PATH`, `PIXELLAB_API_KEY`, `PROPOSALS_DIR`, `REVIEWS_DIR`, `USER`. 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-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:\nsrc/ohmystock/backtest/portfolio.py:apply_buy, src/ohmystock/backtest/portfolio.py:apply_sell\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-33a6b62e30ce7ab4", "name": "Near-duplicate function bodies in 6 places", "shortDescription": {"text": "Near-duplicate function bodies in 6 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nsrc/ohmystock/safety/confirm_gate.py:now_iso, src/ohmystock/safety/confirm_gate.py:now_iso, src/ohmystock/safety/auto_execute.py:now_iso, src/ohmystock/safety/auto_execute.py:now_iso\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-49c98f7cedd9c977", "name": "Near-duplicate function bodies in 4 places", "shortDescription": {"text": "Near-duplicate function bodies in 4 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nsrc/ohmystock/swarm/_adapters.py:get, src/ohmystock/swarm/_adapters.py:get, src/ohmystock/swarm/_adapters.py:get, src/ohmystock/swarm/_adapters.py:get\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-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:\nsrc/ohmystock/review/llm_client.py:complete, src/ohmystock/review/llm_client.py:complete, src/ohmystock/review/llm_client.py:complete\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-6280a3893846b95c", "name": "Frontend route `/skills/:name` has no Link/navigate to it \u2014 web-admin/src/pages/__tests__/SkillsPage.test.tsx", "shortDescription": {"text": "Frontend route `/skills/:name` has no Link/navigate to it \u2014 web-admin/src/pages/__tests__/SkillsPage.test.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4b8646d7f66be500", "name": "Frontend route `/proposals/:slug` has no Link/navigate to it \u2014 web-admin/src/pages/__tests__/ProposalDetailPage.test.tsx", "shortDescription": {"text": "Frontend route `/proposals/:slug` has no Link/navigate to it \u2014 web-admin/src/pages/__tests__/ProposalDetailPage.test.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2105ffa82dc366e1", "name": "FastAPI POST `run_exit_engine` without auth dependency \u2014 src/ohmystock/api/routes/exit_engine.py:87", "shortDescription": {"text": "FastAPI POST `run_exit_engine` without auth dependency \u2014 src/ohmystock/api/routes/exit_engine.py:87"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-38b1615f1aad6e84", "name": "FastAPI POST `run_screener` without auth dependency \u2014 src/ohmystock/api/routes/screener.py:48", "shortDescription": {"text": "FastAPI POST `run_screener` without auth dependency \u2014 src/ohmystock/api/routes/screener.py:48"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8e4689f332804059", "name": "FastAPI POST `transition_proposal_endpoint` without auth dependency \u2014 src/ohmystock/api/routes/proposals.py:602", "shortDescription": {"text": "FastAPI POST `transition_proposal_endpoint` without auth dependency \u2014 src/ohmystock/api/routes/proposals.py:602"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-03bebea7da61808d", "name": "FastAPI POST `validate_proposal_endpoint` without auth dependency \u2014 src/ohmystock/api/routes/proposals.py:666", "shortDescription": {"text": "FastAPI POST `validate_proposal_endpoint` without auth dependency \u2014 src/ohmystock/api/routes/proposals.py:666"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c7dea5881c2e806f", "name": "FastAPI POST `create_memory_row` without auth dependency \u2014 src/ohmystock/api/routes/memory.py:125", "shortDescription": {"text": "FastAPI POST `create_memory_row` without auth dependency \u2014 src/ohmystock/api/routes/memory.py:125"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ff1ec1590ba6cd9f", "name": "FastAPI POST `post_confirm` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:125", "shortDescription": {"text": "FastAPI POST `post_confirm` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:125"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-be0a56b7ebdfc2ae", "name": "FastAPI POST `post_reject` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:167", "shortDescription": {"text": "FastAPI POST `post_reject` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:167"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-71e523a3cd94d31b", "name": "FastAPI POST `post_sweep_expired` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:204", "shortDescription": {"text": "FastAPI POST `post_sweep_expired` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:204"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-49f9b5ce7aaa9b1c", "name": "FastAPI POST `post_run` without auth dependency \u2014 src/ohmystock/api/routes/backtest.py:403", "shortDescription": {"text": "FastAPI POST `post_run` without auth dependency \u2014 src/ohmystock/api/routes/backtest.py:403"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-92c792ef4b86e7b2", "name": "FastAPI POST `post_run` without auth dependency \u2014 src/ohmystock/api/routes/swarm.py:141", "shortDescription": {"text": "FastAPI POST `post_run` without auth dependency \u2014 src/ohmystock/api/routes/swarm.py:141"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d114e185e207caf8", "name": "FastAPI POST `create_chat_session` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:230", "shortDescription": {"text": "FastAPI POST `create_chat_session` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:230"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fc37138f25b7806d", "name": "FastAPI DELETE `delete_chat_session` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:321", "shortDescription": {"text": "FastAPI DELETE `delete_chat_session` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:321"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-becc476eabcb857a", "name": "FastAPI POST `send_chat_message` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:352", "shortDescription": {"text": "FastAPI POST `send_chat_message` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:352"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-069497fdcf49e8ac", "name": "FastAPI POST `post_test_connection` without auth dependency \u2014 src/ohmystock/api/routes/settings.py:167", "shortDescription": {"text": "FastAPI POST `post_test_connection` without auth dependency \u2014 src/ohmystock/api/routes/settings.py:167"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-d6175303a143ca19", "name": "Unused endpoint: GET /api/admin/events", "shortDescription": {"text": "Unused endpoint: GET /api/admin/events"}, "fullDescription": {"text": "`src/ohmystock/api/app.py` declares `GET /api/admin/events` 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-8a9ce53937d52509", "name": "Unused endpoint: POST /api/admin/exit-engine/run", "shortDescription": {"text": "Unused endpoint: POST /api/admin/exit-engine/run"}, "fullDescription": {"text": "`src/ohmystock/api/routes/exit_engine.py` declares `POST /api/admin/exit-engine/run` 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-9d2a59196ccc10f2", "name": "Unused endpoint: GET /api/admin/skills", "shortDescription": {"text": "Unused endpoint: GET /api/admin/skills"}, "fullDescription": {"text": "`src/ohmystock/api/routes/skills.py` declares `GET /api/admin/skills` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-55d97240fbfccd52", "name": "Unused endpoint: GET /api/admin/skills/{name:path}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/skills/{name:path}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/skills.py` declares `GET /api/admin/skills/{name:path}` 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-43269e4e79c2e69e", "name": "Unused endpoint: GET /events", "shortDescription": {"text": "Unused endpoint: GET /events"}, "fullDescription": {"text": "`src/ohmystock/api/routes/public_events.py` declares `GET /events` 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-4d00d4bf2a459e61", "name": "Unused endpoint: POST /api/admin/screener/run", "shortDescription": {"text": "Unused endpoint: POST /api/admin/screener/run"}, "fullDescription": {"text": "`src/ohmystock/api/routes/screener.py` declares `POST /api/admin/screener/run` 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-154d5e81f2fbc9ac", "name": "Unused endpoint: GET /api/admin/proposals", "shortDescription": {"text": "Unused endpoint: GET /api/admin/proposals"}, "fullDescription": {"text": "`src/ohmystock/api/routes/proposals.py` declares `GET /api/admin/proposals` 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-70270059bbf440dc", "name": "Unused endpoint: GET /api/admin/proposals/{slug:path}/transition", "shortDescription": {"text": "Unused endpoint: GET /api/admin/proposals/{slug:path}/transition"}, "fullDescription": {"text": "`src/ohmystock/api/routes/proposals.py` declares `GET /api/admin/proposals/{slug:path}/transition` 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-81ab25aa6b37841a", "name": "Unused endpoint: GET /api/admin/proposals/{slug:path}/validate", "shortDescription": {"text": "Unused endpoint: GET /api/admin/proposals/{slug:path}/validate"}, "fullDescription": {"text": "`src/ohmystock/api/routes/proposals.py` declares `GET /api/admin/proposals/{slug:path}/validate` 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-d8ef2d8c6b4064ed", "name": "Unused endpoint: GET /api/admin/proposals/{slug:path}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/proposals/{slug:path}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/proposals.py` declares `GET /api/admin/proposals/{slug:path}` 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-d314f42f3d2cef6e", "name": "Unused endpoint: POST /api/admin/proposals/{slug:path}/transition", "shortDescription": {"text": "Unused endpoint: POST /api/admin/proposals/{slug:path}/transition"}, "fullDescription": {"text": "`src/ohmystock/api/routes/proposals.py` declares `POST /api/admin/proposals/{slug:path}/transition` 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-d663e5adfcf6cdb6", "name": "Unused endpoint: POST /api/admin/proposals/{slug:path}/validate", "shortDescription": {"text": "Unused endpoint: POST /api/admin/proposals/{slug:path}/validate"}, "fullDescription": {"text": "`src/ohmystock/api/routes/proposals.py` declares `POST /api/admin/proposals/{slug:path}/validate` 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-a64a3407b564809b", "name": "Unused endpoint: GET /api/admin/memory/rows", "shortDescription": {"text": "Unused endpoint: GET /api/admin/memory/rows"}, "fullDescription": {"text": "`src/ohmystock/api/routes/memory.py` declares `GET /api/admin/memory/rows` 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-0601bb7cf0cd47df", "name": "Unused endpoint: POST /api/admin/memory/rows", "shortDescription": {"text": "Unused endpoint: POST /api/admin/memory/rows"}, "fullDescription": {"text": "`src/ohmystock/api/routes/memory.py` declares `POST /api/admin/memory/rows` 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-c83c88a4c94c43d6", "name": "Unused endpoint: GET /api/admin/memory/search", "shortDescription": {"text": "Unused endpoint: GET /api/admin/memory/search"}, "fullDescription": {"text": "`src/ohmystock/api/routes/memory.py` declares `GET /api/admin/memory/search` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5628d010b08e486c", "name": "Unused endpoint: GET /api/admin/confirm-gate/pending", "shortDescription": {"text": "Unused endpoint: GET /api/admin/confirm-gate/pending"}, "fullDescription": {"text": "`src/ohmystock/api/routes/confirm_gate.py` declares `GET /api/admin/confirm-gate/pending` 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-c21c90a0f3295037", "name": "Unused endpoint: POST /api/admin/confirm-gate/confirm", "shortDescription": {"text": "Unused endpoint: POST /api/admin/confirm-gate/confirm"}, "fullDescription": {"text": "`src/ohmystock/api/routes/confirm_gate.py` declares `POST /api/admin/confirm-gate/confirm` 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-fe324251ca8c1a77", "name": "Unused endpoint: POST /api/admin/confirm-gate/reject", "shortDescription": {"text": "Unused endpoint: POST /api/admin/confirm-gate/reject"}, "fullDescription": {"text": "`src/ohmystock/api/routes/confirm_gate.py` declares `POST /api/admin/confirm-gate/reject` 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-7f370b6e7e70482a", "name": "Unused endpoint: POST /api/admin/confirm-gate/sweep-expired", "shortDescription": {"text": "Unused endpoint: POST /api/admin/confirm-gate/sweep-expired"}, "fullDescription": {"text": "`src/ohmystock/api/routes/confirm_gate.py` declares `POST /api/admin/confirm-gate/sweep-expired` 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-3a8b2a4ce3dfcc41", "name": "Unused endpoint: GET /api/admin/backtest/strategies", "shortDescription": {"text": "Unused endpoint: GET /api/admin/backtest/strategies"}, "fullDescription": {"text": "`src/ohmystock/api/routes/backtest.py` declares `GET /api/admin/backtest/strategies` 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-501e27bdf5f840b2", "name": "Unused endpoint: POST /api/admin/backtest/run", "shortDescription": {"text": "Unused endpoint: POST /api/admin/backtest/run"}, "fullDescription": {"text": "`src/ohmystock/api/routes/backtest.py` declares `POST /api/admin/backtest/run` 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-f0f508f01cfe0c3b", "name": "Unused endpoint: GET /api/admin/backtest/jobs", "shortDescription": {"text": "Unused endpoint: GET /api/admin/backtest/jobs"}, "fullDescription": {"text": "`src/ohmystock/api/routes/backtest.py` declares `GET /api/admin/backtest/jobs` 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-1c5d6556772810a0", "name": "Unused endpoint: GET /api/admin/backtest/jobs/{job_id}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/backtest/jobs/{job_id}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/backtest.py` declares `GET /api/admin/backtest/jobs/{job_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-caa04a319fa3721c", "name": "Unused endpoint: GET /api/admin/journal/rows", "shortDescription": {"text": "Unused endpoint: GET /api/admin/journal/rows"}, "fullDescription": {"text": "`src/ohmystock/api/routes/journal.py` declares `GET /api/admin/journal/rows` 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-d118b81f358504d3", "name": "Unused endpoint: GET /api/admin/journal/decisions/{decision_id}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/journal/decisions/{decision_id}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/journal.py` declares `GET /api/admin/journal/decisions/{decision_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e3a64f73908ebbf2", "name": "Unused endpoint: GET /presets", "shortDescription": {"text": "Unused endpoint: GET /presets"}, "fullDescription": {"text": "`src/ohmystock/api/routes/swarm.py` declares `GET /presets` 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-9daeb7b1a43e9733", "name": "Unused endpoint: POST /runs", "shortDescription": {"text": "Unused endpoint: POST /runs"}, "fullDescription": {"text": "`src/ohmystock/api/routes/swarm.py` declares `POST /runs` 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-3be912c6187ea599", "name": "Unused endpoint: GET /runs", "shortDescription": {"text": "Unused endpoint: GET /runs"}, "fullDescription": {"text": "`src/ohmystock/api/routes/swarm.py` declares `GET /runs` 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-1d0346edb562dc8a", "name": "Unused endpoint: GET /runs/{run_id:path}", "shortDescription": {"text": "Unused endpoint: GET /runs/{run_id:path}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/swarm.py` declares `GET /runs/{run_id:path}` 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-741caada6101f5fd", "name": "Unused endpoint: GET /api/admin/chat/sessions", "shortDescription": {"text": "Unused endpoint: GET /api/admin/chat/sessions"}, "fullDescription": {"text": "`src/ohmystock/api/routes/chat.py` declares `GET /api/admin/chat/sessions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-609e13abcb40c015", "name": "Unused endpoint: POST /api/admin/chat/sessions", "shortDescription": {"text": "Unused endpoint: POST /api/admin/chat/sessions"}, "fullDescription": {"text": "`src/ohmystock/api/routes/chat.py` declares `POST /api/admin/chat/sessions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-39f60b594ae48a43", "name": "Unused endpoint: GET /api/admin/chat/sessions/{session_id:path}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/chat/sessions/{session_id:path}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/chat.py` declares `GET /api/admin/chat/sessions/{session_id:path}` 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-236e29bc3d95d293", "name": "Unused endpoint: DELETE /api/admin/chat/sessions/{session_id:path}", "shortDescription": {"text": "Unused endpoint: DELETE /api/admin/chat/sessions/{session_id:path}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/chat.py` declares `DELETE /api/admin/chat/sessions/{session_id:path}` 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-505fc9062c9fa87d", "name": "Unused endpoint: GET /api/admin/chat/search", "shortDescription": {"text": "Unused endpoint: GET /api/admin/chat/search"}, "fullDescription": {"text": "`src/ohmystock/api/routes/chat.py` declares `GET /api/admin/chat/search` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6f2f19502d8f02d1", "name": "Unused endpoint: GET /api/admin/market/symbols/{symbol}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/market/symbols/{symbol}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/market.py` declares `GET /api/admin/market/symbols/{symbol}` 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-c87571933571c140", "name": "Unused endpoint: GET /api/admin/reviews", "shortDescription": {"text": "Unused endpoint: GET /api/admin/reviews"}, "fullDescription": {"text": "`src/ohmystock/api/routes/reviews.py` declares `GET /api/admin/reviews` 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-8c4322487fb334b0", "name": "Unused endpoint: GET /api/admin/reviews/{review_id}", "shortDescription": {"text": "Unused endpoint: GET /api/admin/reviews/{review_id}"}, "fullDescription": {"text": "`src/ohmystock/api/routes/reviews.py` declares `GET /api/admin/reviews/{review_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-129760448f975ac2", "name": "Unused endpoint: GET /api/admin/settings", "shortDescription": {"text": "Unused endpoint: GET /api/admin/settings"}, "fullDescription": {"text": "`src/ohmystock/api/routes/settings.py` declares `GET /api/admin/settings` 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-25c6f739081e5e01", "name": "Unused endpoint: POST /api/admin/settings/test-connection", "shortDescription": {"text": "Unused endpoint: POST /api/admin/settings/test-connection"}, "fullDescription": {"text": "`src/ohmystock/api/routes/settings.py` declares `POST /api/admin/settings/test-connection` 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-f6dfed9513da17ed", "name": "Unused endpoint: GET /api/admin/stats/today", "shortDescription": {"text": "Unused endpoint: GET /api/admin/stats/today"}, "fullDescription": {"text": "`src/ohmystock/api/routes/stats.py` declares `GET /api/admin/stats/today` 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-f2c257c6f6d4efa2", "name": "Unused endpoint: GET /api/admin/positions/open", "shortDescription": {"text": "Unused endpoint: GET /api/admin/positions/open"}, "fullDescription": {"text": "`src/ohmystock/api/routes/positions.py` declares `GET /api/admin/positions/open` 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/17580"}, "properties": {"repository": "qazwsx123851/ohMyStock", "repoUrl": "https://github.com/qazwsx123851/ohMyStock", "branch": "main"}, "results": [{"ruleId": "scanner-af9640d94356191e", "level": "note", "message": {"text": "Possibly dead Python function: validate_proposal"}, "properties": {"repobilityId": "c4a94d3e1aa0a5b9", "scanner": "scanner-primary", "fingerprint": "af9640d94356191e", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/cli/_validate_proposal.py:96"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-42b94adf4d67e3a8", "level": "note", "message": {"text": "Possibly dead Python function: assemble_entry_input"}, "properties": {"repobilityId": "057acd3ff9b46063", "scanner": "scanner-primary", "fingerprint": "42b94adf4d67e3a8", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/cli/_assemble.py:179"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f4580bef2cffb14f", "level": "note", "message": {"text": "Possibly dead Python function: confirm_command"}, "properties": {"repobilityId": "3201d73ba6fea930", "scanner": "scanner-primary", "fingerprint": "f4580bef2cffb14f", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/cli/_confirm.py:72"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d96fc967edc01b92", "level": "note", "message": {"text": "Possibly dead Python function: evaluate_exits"}, "properties": {"repobilityId": "753db8bf62ada7c4", "scanner": "scanner-primary", "fingerprint": "d96fc967edc01b92", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/cli/_evaluate_exits.py:110"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ea916f1acb850dc", "level": "note", "message": {"text": "Possibly dead Python function: review_cmd"}, "properties": {"repobilityId": "5a4b24ea99e2bce7", "scanner": "scanner-primary", "fingerprint": "3ea916f1acb850dc", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/cli/_review.py:54"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ddf445f924a72610", "level": "note", "message": {"text": "Possibly dead Python function: decorator"}, "properties": {"repobilityId": "ffbcbc9bc189af1c", "scanner": "scanner-primary", "fingerprint": "ddf445f924a72610", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/observability/cost_tracker.py:60"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c89eae4f16d49318", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/components/layout.tsx:141"}, "properties": {"repobilityId": "409d348bd5d93405", "scanner": "scanner-primary", "fingerprint": "c89eae4f16d49318", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ef602aac78a98e19", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/ChatSessionPage.tsx:399"}, "properties": {"repobilityId": "11746da33e1c9aa8", "scanner": "scanner-primary", "fingerprint": "ef602aac78a98e19", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d31d31734e3898ed", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/ReviewDetailPage.tsx:211"}, "properties": {"repobilityId": "b09d949616973472", "scanner": "scanner-primary", "fingerprint": "d31d31734e3898ed", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-00f27064fac81501", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/PaperOverviewPage.tsx:127"}, "properties": {"repobilityId": "ac3daf6cd93ab38f", "scanner": "scanner-primary", "fingerprint": "00f27064fac81501", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9aaeadee3fa8909c", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 web-admin/src/pages/SessionsPage.tsx:34"}, "properties": {"repobilityId": "be6bc1f471bebf71", "scanner": "scanner-primary", "fingerprint": "9aaeadee3fa8909c", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-d5ef3bc5aeb372b0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/MarketPage.tsx:246"}, "properties": {"repobilityId": "d2260b5137b06130", "scanner": "scanner-primary", "fingerprint": "d5ef3bc5aeb372b0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eef88486e9d0d268", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/AuditPage.tsx:157"}, "properties": {"repobilityId": "9b238d588a1d352c", "scanner": "scanner-primary", "fingerprint": "eef88486e9d0d268", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-28808fc4d6bb9721", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 web-admin/src/pages/DashboardPage.tsx:221"}, "properties": {"repobilityId": "7a9b9196adac7b7b", "scanner": "scanner-primary", "fingerprint": "28808fc4d6bb9721", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5292ed8116f6d043", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in web-admin/e2e/global-setup.ts:1"}, "properties": {"repobilityId": "0320598f752ff07e", "scanner": "scanner-primary", "fingerprint": "5292ed8116f6d043", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web-admin/e2e/global-setup.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-a949d199616af067", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: web-admin/e2e/package.json"}, "properties": {"repobilityId": "d85680d37d27d894", "scanner": "scanner-primary", "fingerprint": "a949d199616af067", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "web-admin/e2e/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "b3dc410fb9e05201", "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": "1b50372c15d0b51c", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "b3ed08b0682446b3", "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": "6be17e7a72f46874", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "f14b0f6f3af9c692", "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": "2bc480a49249502f", "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": "8dedb05bd83620b0", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-10be1b379989d3a6", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/rules/capability-map.md"}, "properties": {"repobilityId": "464a9c23b00e4a9c", "scanner": "scanner-primary", "fingerprint": "10be1b379989d3a6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/rules/capability-map.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8e1c592f3726c637", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/rules/ssot-pointers.md"}, "properties": {"repobilityId": "44d128712368e7d4", "scanner": "scanner-primary", "fingerprint": "8e1c592f3726c637", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/rules/ssot-pointers.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-df8d7aecf447de62", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/commands/opsx/archive.md"}, "properties": {"repobilityId": "222623e99b9cb4f7", "scanner": "scanner-primary", "fingerprint": "df8d7aecf447de62", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/commands/opsx/archive.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-021b572fe2fa6b9c", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/commands/opsx/apply.md"}, "properties": {"repobilityId": "5ba922ec1bca34d1", "scanner": "scanner-primary", "fingerprint": "021b572fe2fa6b9c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/commands/opsx/apply.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-14b94de34d897ad4", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/openspec-apply-change/SKILL.md"}, "properties": {"repobilityId": "ff525910a58aad1b", "scanner": "scanner-primary", "fingerprint": "14b94de34d897ad4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/openspec-apply-change/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8a585f74bb40a5f1", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/openspec-archive-change/SKILL.md"}, "properties": {"repobilityId": "1499167b45dee6be", "scanner": "scanner-primary", "fingerprint": "8a585f74bb40a5f1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/openspec-archive-change/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-63d623eb7d1828ef", "level": "note", "message": {"text": "Legacy-named symbol `dec_old` in tests/test_live_journal_provider.py:206"}, "properties": {"repobilityId": "3974fffeeda6e19a", "scanner": "scanner-primary", "fingerprint": "63d623eb7d1828ef", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-deed588c64acd74d", "level": "note", "message": {"text": "Legacy-named symbol `dec_old` in tests/test_confirm_gate.py:552"}, "properties": {"repobilityId": "165cd8a021ad34c0", "scanner": "scanner-primary", "fingerprint": "deed588c64acd74d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-923f56b3bab27a24", "level": "note", "message": {"text": "Legacy-named symbol `test_serialize_payload_is_same_reference_no_deep_copy` in tests/test_admin_event_serializer.py:45"}, "properties": {"repobilityId": "d8e4c1782d37e54b", "scanner": "scanner-primary", "fingerprint": "923f56b3bab27a24", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f9ea29896c194ee2", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in tests/test_input_assembler_snapshot.py:219"}, "properties": {"repobilityId": "81b0041f481c3b39", "scanner": "scanner-primary", "fingerprint": "f9ea29896c194ee2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-2d0e42a1ef0eacda", "level": "none", "message": {"text": "Commented-code block (5 lines) in tests/test_decider_orchestrator.py:226"}, "properties": {"repobilityId": "b4eed947ca88c30d", "scanner": "scanner-primary", "fingerprint": "2d0e42a1ef0eacda", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-307af0aa460b5a37", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in tests/test_decider_validator.py:127"}, "properties": {"repobilityId": "f4b83277de929d7a", "scanner": "scanner-primary", "fingerprint": "307af0aa460b5a37", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a2225470d15d3bef", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in tests/proposal/test_round_trip.py:86"}, "properties": {"repobilityId": "38e450bd73e536a2", "scanner": "scanner-primary", "fingerprint": "a2225470d15d3bef", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-90d6f4d264293511", "level": "none", "message": {"text": "Commented-code block (5 lines) in web-admin/src/lib/journal-kinds.ts:1"}, "properties": {"repobilityId": "e8b01b3cd3db96f2", "scanner": "scanner-primary", "fingerprint": "90d6f4d264293511", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f6f1c76871139855", "level": "none", "message": {"text": "Commented-code block (5 lines) in web-admin/e2e/playwright.config.ts:14"}, "properties": {"repobilityId": "286d1c460f87157f", "scanner": "scanner-primary", "fingerprint": "f6f1c76871139855", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5a3daf2b01dbf794", "level": "none", "message": {"text": "Commented-code block (5 lines) in web-admin/e2e/constants.ts:4"}, "properties": {"repobilityId": "a15688b8d024621f", "scanner": "scanner-primary", "fingerprint": "5a3daf2b01dbf794", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-166bf66572562fad", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 web-public/scripts/fetch_pixellab_sheets.py:52"}, "properties": {"repobilityId": "a1805ba97a122e20", "scanner": "scanner-primary", "fingerprint": "166bf66572562fad", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-66870dab2c888195", "level": "note", "message": {"text": "Legacy-named symbol `future_unknown_v2` in web-public/src/__tests__/usePublicSSE.test.tsx:77"}, "properties": {"repobilityId": "c4601abcb9928b17", "scanner": "scanner-primary", "fingerprint": "66870dab2c888195", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a84194d0724415d3", "level": "note", "message": {"text": "Legacy-named symbol `future_unknown_v2` in web-public/src/__tests__/eventToAction.test.ts:84"}, "properties": {"repobilityId": "b3fb0b1f1172b195", "scanner": "scanner-primary", "fingerprint": "a84194d0724415d3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-0f80c33e68b0a6bc", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/ohmystock/config.py:93"}, "properties": {"repobilityId": "babbfdc01b647dac", "scanner": "scanner-primary", "fingerprint": "0f80c33e68b0a6bc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b654fb49cdbbacec", "level": "note", "message": {"text": "Legacy-named symbol `_migrate_kind_check_if_legacy` in src/ohmystock/journal/schema.py:131"}, "properties": {"repobilityId": "82a13d0142a0a444", "scanner": "scanner-primary", "fingerprint": "b654fb49cdbbacec", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-72e208dc2b8f8b2b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/ohmystock/api/db.py:48"}, "properties": {"repobilityId": "4d56db10e17836db", "scanner": "scanner-primary", "fingerprint": "72e208dc2b8f8b2b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b6f4c06ae5805b60", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/ohmystock/api/routes/proposals.py:80"}, "properties": {"repobilityId": "be2666c707502295", "scanner": "scanner-primary", "fingerprint": "b6f4c06ae5805b60", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-955725fdfc53d6db", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in src/ohmystock/decider/validator.py:72"}, "properties": {"repobilityId": "75c2ce20782f4638", "scanner": "scanner-primary", "fingerprint": "955725fdfc53d6db", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8e047ab7af03962f", "level": "note", "message": {"text": "7 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "5a0455f6498c27ad", "scanner": "scanner-primary", "fingerprint": "8e047ab7af03962f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "c09b72b2bdf39552", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-33a6b62e30ce7ab4", "level": "note", "message": {"text": "Near-duplicate function bodies in 6 places"}, "properties": {"repobilityId": "88136aa8ec9734ce", "scanner": "scanner-primary", "fingerprint": "33a6b62e30ce7ab4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-49c98f7cedd9c977", "level": "note", "message": {"text": "Near-duplicate function bodies in 4 places"}, "properties": {"repobilityId": "fd4e458e4141d270", "scanner": "scanner-primary", "fingerprint": "49c98f7cedd9c977", "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": "4560f50ba5e60740", "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": "a22ae8ce39996e3f", "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": "65b91a83bfeecac5", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "71170ef6c8067680", "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": "41b4829ef9be6625", "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": "f510f9d0b7488d2b", "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": "6942b1b8706f74a6", "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": "feda3c8b83f6dcb5", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "84bb0182c42990c7", "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": "09d51aa564fdb801", "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": "cf360ae179ab1327", "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": "7b9a1e91a16c0bec", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "16c51e47e1751fba", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-6280a3893846b95c", "level": "warning", "message": {"text": "Frontend route `/skills/:name` has no Link/navigate to it \u2014 web-admin/src/pages/__tests__/SkillsPage.test.tsx"}, "properties": {"repobilityId": "a27e5de6c2e3b316", "scanner": "scanner-primary", "fingerprint": "6280a3893846b95c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-4b8646d7f66be500", "level": "warning", "message": {"text": "Frontend route `/proposals/:slug` has no Link/navigate to it \u2014 web-admin/src/pages/__tests__/ProposalDetailPage.test.tsx"}, "properties": {"repobilityId": "e270da91a0c99ef9", "scanner": "scanner-primary", "fingerprint": "4b8646d7f66be500", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-2105ffa82dc366e1", "level": "error", "message": {"text": "FastAPI POST `run_exit_engine` without auth dependency \u2014 src/ohmystock/api/routes/exit_engine.py:87"}, "properties": {"repobilityId": "881f5d84d6ff2206", "scanner": "scanner-primary", "fingerprint": "2105ffa82dc366e1", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/exit_engine.py"}, "region": {"startLine": 87}}}]}, {"ruleId": "scanner-38b1615f1aad6e84", "level": "error", "message": {"text": "FastAPI POST `run_screener` without auth dependency \u2014 src/ohmystock/api/routes/screener.py:48"}, "properties": {"repobilityId": "bcded9b8a7b5d694", "scanner": "scanner-primary", "fingerprint": "38b1615f1aad6e84", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/screener.py"}, "region": {"startLine": 48}}}]}, {"ruleId": "scanner-8e4689f332804059", "level": "error", "message": {"text": "FastAPI POST `transition_proposal_endpoint` without auth dependency \u2014 src/ohmystock/api/routes/proposals.py:602"}, "properties": {"repobilityId": "6c140604f517aefd", "scanner": "scanner-primary", "fingerprint": "8e4689f332804059", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/proposals.py"}, "region": {"startLine": 602}}}]}, {"ruleId": "scanner-03bebea7da61808d", "level": "error", "message": {"text": "FastAPI POST `validate_proposal_endpoint` without auth dependency \u2014 src/ohmystock/api/routes/proposals.py:666"}, "properties": {"repobilityId": "d646ba82254f38fa", "scanner": "scanner-primary", "fingerprint": "03bebea7da61808d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/proposals.py"}, "region": {"startLine": 666}}}]}, {"ruleId": "scanner-c7dea5881c2e806f", "level": "error", "message": {"text": "FastAPI POST `create_memory_row` without auth dependency \u2014 src/ohmystock/api/routes/memory.py:125"}, "properties": {"repobilityId": "7302fe2f137366ce", "scanner": "scanner-primary", "fingerprint": "c7dea5881c2e806f", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/memory.py"}, "region": {"startLine": 125}}}]}, {"ruleId": "scanner-ff1ec1590ba6cd9f", "level": "error", "message": {"text": "FastAPI POST `post_confirm` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:125"}, "properties": {"repobilityId": "4bfa66a01cf771fb", "scanner": "scanner-primary", "fingerprint": "ff1ec1590ba6cd9f", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/confirm_gate.py"}, "region": {"startLine": 125}}}]}, {"ruleId": "scanner-be0a56b7ebdfc2ae", "level": "error", "message": {"text": "FastAPI POST `post_reject` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:167"}, "properties": {"repobilityId": "a9f82c8c9a1ca488", "scanner": "scanner-primary", "fingerprint": "be0a56b7ebdfc2ae", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/confirm_gate.py"}, "region": {"startLine": 167}}}]}, {"ruleId": "scanner-71e523a3cd94d31b", "level": "error", "message": {"text": "FastAPI POST `post_sweep_expired` without auth dependency \u2014 src/ohmystock/api/routes/confirm_gate.py:204"}, "properties": {"repobilityId": "e2158ea479dca3ee", "scanner": "scanner-primary", "fingerprint": "71e523a3cd94d31b", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/confirm_gate.py"}, "region": {"startLine": 204}}}]}, {"ruleId": "scanner-49f9b5ce7aaa9b1c", "level": "error", "message": {"text": "FastAPI POST `post_run` without auth dependency \u2014 src/ohmystock/api/routes/backtest.py:403"}, "properties": {"repobilityId": "4d3dc84936ce95fc", "scanner": "scanner-primary", "fingerprint": "49f9b5ce7aaa9b1c", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/backtest.py"}, "region": {"startLine": 403}}}]}, {"ruleId": "scanner-92c792ef4b86e7b2", "level": "error", "message": {"text": "FastAPI POST `post_run` without auth dependency \u2014 src/ohmystock/api/routes/swarm.py:141"}, "properties": {"repobilityId": "4a422805f031d912", "scanner": "scanner-primary", "fingerprint": "92c792ef4b86e7b2", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/swarm.py"}, "region": {"startLine": 141}}}]}, {"ruleId": "scanner-d114e185e207caf8", "level": "error", "message": {"text": "FastAPI POST `create_chat_session` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:230"}, "properties": {"repobilityId": "9eef958a1840a740", "scanner": "scanner-primary", "fingerprint": "d114e185e207caf8", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/chat.py"}, "region": {"startLine": 230}}}]}, {"ruleId": "scanner-fc37138f25b7806d", "level": "error", "message": {"text": "FastAPI DELETE `delete_chat_session` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:321"}, "properties": {"repobilityId": "3dc4eeb41a67edd0", "scanner": "scanner-primary", "fingerprint": "fc37138f25b7806d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/chat.py"}, "region": {"startLine": 321}}}]}, {"ruleId": "scanner-becc476eabcb857a", "level": "error", "message": {"text": "FastAPI POST `send_chat_message` without auth dependency \u2014 src/ohmystock/api/routes/chat.py:352"}, "properties": {"repobilityId": "4e12e971bdbf8634", "scanner": "scanner-primary", "fingerprint": "becc476eabcb857a", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/chat.py"}, "region": {"startLine": 352}}}]}, {"ruleId": "scanner-069497fdcf49e8ac", "level": "error", "message": {"text": "FastAPI POST `post_test_connection` without auth dependency \u2014 src/ohmystock/api/routes/settings.py:167"}, "properties": {"repobilityId": "c20b76bf4c9013e8", "scanner": "scanner-primary", "fingerprint": "069497fdcf49e8ac", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/ohmystock/api/routes/settings.py"}, "region": {"startLine": 167}}}]}, {"ruleId": "scanner-d6175303a143ca19", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/events"}, "properties": {"repobilityId": "fb6462628f7d7154", "scanner": "scanner-primary", "fingerprint": "d6175303a143ca19", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8a9ce53937d52509", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/exit-engine/run"}, "properties": {"repobilityId": "4d863b16d40247e2", "scanner": "scanner-primary", "fingerprint": "8a9ce53937d52509", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9d2a59196ccc10f2", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/skills"}, "properties": {"repobilityId": "31986f58ed12be21", "scanner": "scanner-primary", "fingerprint": "9d2a59196ccc10f2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-55d97240fbfccd52", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/skills/{name:path}"}, "properties": {"repobilityId": "b1b39eb2b2ebb667", "scanner": "scanner-primary", "fingerprint": "55d97240fbfccd52", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-43269e4e79c2e69e", "level": "note", "message": {"text": "Unused endpoint: GET /events"}, "properties": {"repobilityId": "a6dfe848a139a8b3", "scanner": "scanner-primary", "fingerprint": "43269e4e79c2e69e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4d00d4bf2a459e61", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/screener/run"}, "properties": {"repobilityId": "21671db5798d5db5", "scanner": "scanner-primary", "fingerprint": "4d00d4bf2a459e61", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-154d5e81f2fbc9ac", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/proposals"}, "properties": {"repobilityId": "cb8a8514d7194ca9", "scanner": "scanner-primary", "fingerprint": "154d5e81f2fbc9ac", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-70270059bbf440dc", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/proposals/{slug:path}/transition"}, "properties": {"repobilityId": "123b39635197b739", "scanner": "scanner-primary", "fingerprint": "70270059bbf440dc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-81ab25aa6b37841a", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/proposals/{slug:path}/validate"}, "properties": {"repobilityId": "267cc65a37587be0", "scanner": "scanner-primary", "fingerprint": "81ab25aa6b37841a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d8ef2d8c6b4064ed", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/proposals/{slug:path}"}, "properties": {"repobilityId": "70b5ab933aa185f9", "scanner": "scanner-primary", "fingerprint": "d8ef2d8c6b4064ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d314f42f3d2cef6e", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/proposals/{slug:path}/transition"}, "properties": {"repobilityId": "e39c4dc58e1eebed", "scanner": "scanner-primary", "fingerprint": "d314f42f3d2cef6e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d663e5adfcf6cdb6", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/proposals/{slug:path}/validate"}, "properties": {"repobilityId": "5898ecf048867715", "scanner": "scanner-primary", "fingerprint": "d663e5adfcf6cdb6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a64a3407b564809b", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/memory/rows"}, "properties": {"repobilityId": "0f4abd371437ce8f", "scanner": "scanner-primary", "fingerprint": "a64a3407b564809b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0601bb7cf0cd47df", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/memory/rows"}, "properties": {"repobilityId": "69335cb7090b7cf2", "scanner": "scanner-primary", "fingerprint": "0601bb7cf0cd47df", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c83c88a4c94c43d6", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/memory/search"}, "properties": {"repobilityId": "ebae1bb974a08533", "scanner": "scanner-primary", "fingerprint": "c83c88a4c94c43d6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5628d010b08e486c", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/confirm-gate/pending"}, "properties": {"repobilityId": "55a4a8fe2bdde193", "scanner": "scanner-primary", "fingerprint": "5628d010b08e486c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c21c90a0f3295037", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/confirm-gate/confirm"}, "properties": {"repobilityId": "78c3ed0122815290", "scanner": "scanner-primary", "fingerprint": "c21c90a0f3295037", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fe324251ca8c1a77", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/confirm-gate/reject"}, "properties": {"repobilityId": "e198d9563eca16c0", "scanner": "scanner-primary", "fingerprint": "fe324251ca8c1a77", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7f370b6e7e70482a", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/confirm-gate/sweep-expired"}, "properties": {"repobilityId": "10df9197df75ec4f", "scanner": "scanner-primary", "fingerprint": "7f370b6e7e70482a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3a8b2a4ce3dfcc41", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/backtest/strategies"}, "properties": {"repobilityId": "4764d7ee3227314d", "scanner": "scanner-primary", "fingerprint": "3a8b2a4ce3dfcc41", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-501e27bdf5f840b2", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/backtest/run"}, "properties": {"repobilityId": "83bf23cb159fca39", "scanner": "scanner-primary", "fingerprint": "501e27bdf5f840b2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f0f508f01cfe0c3b", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/backtest/jobs"}, "properties": {"repobilityId": "b509f71615bff2b4", "scanner": "scanner-primary", "fingerprint": "f0f508f01cfe0c3b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1c5d6556772810a0", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/backtest/jobs/{job_id}"}, "properties": {"repobilityId": "549dbd3c6c88143f", "scanner": "scanner-primary", "fingerprint": "1c5d6556772810a0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-caa04a319fa3721c", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/journal/rows"}, "properties": {"repobilityId": "4a77e299f2adc215", "scanner": "scanner-primary", "fingerprint": "caa04a319fa3721c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d118b81f358504d3", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/journal/decisions/{decision_id}"}, "properties": {"repobilityId": "518ae94d58c752d7", "scanner": "scanner-primary", "fingerprint": "d118b81f358504d3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e3a64f73908ebbf2", "level": "note", "message": {"text": "Unused endpoint: GET /presets"}, "properties": {"repobilityId": "b5ed7d8a6e8b17cc", "scanner": "scanner-primary", "fingerprint": "e3a64f73908ebbf2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9daeb7b1a43e9733", "level": "note", "message": {"text": "Unused endpoint: POST /runs"}, "properties": {"repobilityId": "fb65f3fe6e326f05", "scanner": "scanner-primary", "fingerprint": "9daeb7b1a43e9733", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3be912c6187ea599", "level": "note", "message": {"text": "Unused endpoint: GET /runs"}, "properties": {"repobilityId": "91316e515110c67c", "scanner": "scanner-primary", "fingerprint": "3be912c6187ea599", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1d0346edb562dc8a", "level": "note", "message": {"text": "Unused endpoint: GET /runs/{run_id:path}"}, "properties": {"repobilityId": "9df5f3bc1623f9fa", "scanner": "scanner-primary", "fingerprint": "1d0346edb562dc8a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-741caada6101f5fd", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/chat/sessions"}, "properties": {"repobilityId": "39def4b0ae6003b7", "scanner": "scanner-primary", "fingerprint": "741caada6101f5fd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-609e13abcb40c015", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/chat/sessions"}, "properties": {"repobilityId": "27aacb7a88565a82", "scanner": "scanner-primary", "fingerprint": "609e13abcb40c015", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-39f60b594ae48a43", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/chat/sessions/{session_id:path}"}, "properties": {"repobilityId": "faac02826804b24e", "scanner": "scanner-primary", "fingerprint": "39f60b594ae48a43", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-236e29bc3d95d293", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/admin/chat/sessions/{session_id:path}"}, "properties": {"repobilityId": "ccdfa49e476bc22e", "scanner": "scanner-primary", "fingerprint": "236e29bc3d95d293", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-505fc9062c9fa87d", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/chat/search"}, "properties": {"repobilityId": "ca50b21386c90c0d", "scanner": "scanner-primary", "fingerprint": "505fc9062c9fa87d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f2f19502d8f02d1", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/market/symbols/{symbol}"}, "properties": {"repobilityId": "b2d854289aa0335c", "scanner": "scanner-primary", "fingerprint": "6f2f19502d8f02d1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c87571933571c140", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/reviews"}, "properties": {"repobilityId": "7080dbf1cb22f689", "scanner": "scanner-primary", "fingerprint": "c87571933571c140", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8c4322487fb334b0", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/reviews/{review_id}"}, "properties": {"repobilityId": "f6f5be26fce8f568", "scanner": "scanner-primary", "fingerprint": "8c4322487fb334b0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-129760448f975ac2", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/settings"}, "properties": {"repobilityId": "87e2733673c7345b", "scanner": "scanner-primary", "fingerprint": "129760448f975ac2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-25c6f739081e5e01", "level": "note", "message": {"text": "Unused endpoint: POST /api/admin/settings/test-connection"}, "properties": {"repobilityId": "67821bcc5f530f27", "scanner": "scanner-primary", "fingerprint": "25c6f739081e5e01", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f6dfed9513da17ed", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/stats/today"}, "properties": {"repobilityId": "bd559911a8c92624", "scanner": "scanner-primary", "fingerprint": "f6dfed9513da17ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f2c257c6f6d4efa2", "level": "note", "message": {"text": "Unused endpoint: GET /api/admin/positions/open"}, "properties": {"repobilityId": "e24814ca6cc4bc0a", "scanner": "scanner-primary", "fingerprint": "f2c257c6f6d4efa2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}