{"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-64f2788c30223bf6", "name": "Possibly dead Python function: require_write_access", "shortDescription": {"text": "Possibly dead Python function: require_write_access"}, "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-5162b06b5fdd5355", "name": "Possibly dead Python function: rules_for_domain", "shortDescription": {"text": "Possibly dead Python function: rules_for_domain"}, "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-0634fbd7aaae12d9", "name": "Possibly dead Python function: to_version_dict", "shortDescription": {"text": "Possibly dead Python function: to_version_dict"}, "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-c27c350ce482d2ee", "name": "Possibly dead Python function: create_issue", "shortDescription": {"text": "Possibly dead Python function: create_issue"}, "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-24371b0d8515089a", "name": "Possibly dead Python function: dependency", "shortDescription": {"text": "Possibly dead Python function: dependency"}, "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-e86e9300aabb6319", "name": "Icon-only button without accessible name \u2014 frontend/src/App.jsx:163", "shortDescription": {"text": "Icon-only button without accessible name \u2014 frontend/src/App.jsx:163"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-242d9bc09d95ac17", "name": "Stray `console.log` in TS/JS \u2014 scripts/gen_fix_spec.js:2072", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/gen_fix_spec.js:2072"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e066691601852931", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-60427b03771411b6", "name": "Dockerfile runs as root: frontend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-faa134129e5545ff", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b048d166901fd868", "name": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8750aff3566aef0a", "name": "Insecure pattern 'cors_wildcard' in main.py:117", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in main.py:117"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-550404e32a7a8d83", "name": "Insecure pattern 'local_storage_auth_token' in scripts/gen_fix_spec.js:1230", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in scripts/gen_fix_spec.js:1230"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-49e41960b86672a6", "name": "Insecure pattern 'weak_hash' in .claude/skills/security-audit/SKILL.md:30", "shortDescription": {"text": "Insecure pattern 'weak_hash' in .claude/skills/security-audit/SKILL.md:30"}, "fullDescription": {"text": "Found a known-risky pattern (weak_hash). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-aa1c87f397d3e7bc", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/upload-artifact@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7f4a481c2e5a47e0", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dcd6030ad824412b", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5de4b45d2d113015", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-54d07f12537e2b32", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-75d0a1bf591f9323", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b2f6c3671667214f", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/upload-artifact@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3a99783390a92e1b", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ecd9dba21ccdc4fb", "name": "Very large file: engine.py (2053 lines)", "shortDescription": {"text": "Very large file: engine.py (2053 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-19881c9dec8a10e7", "name": "Very large file: models.py (1185 lines)", "shortDescription": {"text": "Very large file: models.py (1185 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-58e80cf96b7d399c", "name": "Very large file: scripts/gen_fix_spec.js (2075 lines)", "shortDescription": {"text": "Very large file: scripts/gen_fix_spec.js (2075 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 63 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 25 placeholder/mock markers across 15 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-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-19f18bdc1ea8040d", "name": "Agent authority lacks a verifier contract: .claude/agents/security-auditor.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/agents/security-auditor.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-fb401590f323bf07", "name": "Agent instruction/config may expose a secret: .claude/skills/deploy-railway/SKILL.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: .claude/skills/deploy-railway/SKILL.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-4d95dbaa3da5907d", "name": "Agent authority lacks a verifier contract: .claude/skills/rule-pack-edit/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/rule-pack-edit/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-861199178aa5eb94", "name": "Agent authority lacks a verifier contract: .claude/skills/security-audit/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/security-audit/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-68984449f3a63b77", "name": "Commented-code block (5 lines) in database.py:43", "shortDescription": {"text": "Commented-code block (5 lines) in database.py:43"}, "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-6af7d03e03662bb9", "name": "Commented-code block (5 lines) in conftest.py:63", "shortDescription": {"text": "Commented-code block (5 lines) in conftest.py:63"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f78c60312a33a574", "name": "Commented-code block (5 lines) in auth.py:58", "shortDescription": {"text": "Commented-code block (5 lines) in auth.py:58"}, "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-cb797ee2a0006355", "name": "Commented-code block (5 lines) in models.py:253", "shortDescription": {"text": "Commented-code block (5 lines) in models.py:253"}, "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-f9f03c34b023aee6", "name": "Commented-code block (5 lines) in main.py:151", "shortDescription": {"text": "Commented-code block (5 lines) in main.py:151"}, "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-05bc82825b72d005", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api/saro.js:15", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api/saro.js:15"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1e3f97a3c66e1d05", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskForm.jsx:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskForm.jsx:35"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-db7593bf4c63445d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/ComplianceHub.jsx:23", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/ComplianceHub.jsx:23"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e718f7283a47b933", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/DemoEntry.jsx:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/DemoEntry.jsx:21"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-baee9046cc8b9cd3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskDetail.jsx:40", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskDetail.jsx:40"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-21af158fcbfac943", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskSummary.jsx:94", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskSummary.jsx:94"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4a8a39e6265742a5", "name": "Legacy-named symbol `nist_rmf_v1` in tests/test_gap2_notifications.py:122", "shortDescription": {"text": "Legacy-named symbol `nist_rmf_v1` in tests/test_gap2_notifications.py:122"}, "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-c1c2aea2f8728d5b", "name": "Commented-code block (5 lines) in tests/test_epic6_security.py:119", "shortDescription": {"text": "Commented-code block (5 lines) in tests/test_epic6_security.py:119"}, "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-56b6dcaea8e2365e", "name": "Legacy-named symbol `test_no_unqualified_nist_aligned_claims_in_product_copy` in tests/test_pt007_nist_coverage.py:52", "shortDescription": {"text": "Legacy-named symbol `test_no_unqualified_nist_aligned_claims_in_product_copy` in tests/test_pt007_nist_coverage.py:52"}, "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-f5a41fb3e48752ed", "name": "Legacy-named symbol `nist_rmf_v1` in tests/test_epic4_rule_packs.py:55", "shortDescription": {"text": "Legacy-named symbol `nist_rmf_v1` in tests/test_epic4_rule_packs.py:55"}, "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-e2f85339c84b9b0a", "name": "Commented-code block (7 lines) in tests/test_epic4_rule_packs.py:110", "shortDescription": {"text": "Commented-code block (7 lines) in tests/test_epic4_rule_packs.py:110"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a7b593e04681a7ac", "name": "Commented-code block (5 lines) in middleware/rate_limiter.py:28", "shortDescription": {"text": "Commented-code block (5 lines) in middleware/rate_limiter.py:28"}, "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-069a825d53e599da", "name": "Network/subprocess call without timeout or try/except \u2014 scripts/update_quality_baseline.py:20", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/update_quality_baseline.py:20"}, "fullDescription": {"text": "`subprocess.run(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6f9b99c08f4e4b59", "name": "Legacy-named symbol `SARO_Fix_Spec_v1` in scripts/gen_fix_spec.js:4", "shortDescription": {"text": "Legacy-named symbol `SARO_Fix_Spec_v1` in scripts/gen_fix_spec.js:4"}, "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-d318482a32037448", "name": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/gen_fix_spec.js:1165", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/gen_fix_spec.js:1165"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3354e196643a644b", "name": "Commented-code block (8 lines) in saro-data-framework/src/saro_data/converters/guardrails_hallucination.py:30", "shortDescription": {"text": "Commented-code block (8 lines) in saro-data-framework/src/saro_data/converters/guardrails_hallucination.py:30"}, "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-65c519476857dfc4", "name": "Commented-code block (8 lines) in services/evf_qco_service.py:325", "shortDescription": {"text": "Commented-code block (8 lines) in services/evf_qco_service.py:325"}, "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-bf37ac2e096ac8e8", "name": "Legacy-named symbol `partial_legacy` in routers/audit_chain.py:95", "shortDescription": {"text": "Legacy-named symbol `partial_legacy` in routers/audit_chain.py:95"}, "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-8e9bb5c2027ea02b", "name": "Commented-code block (5 lines) in routers/sso.py:45", "shortDescription": {"text": "Commented-code block (5 lines) in routers/sso.py:45"}, "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-5f59c108e846922f", "name": "Network/subprocess call without timeout or try/except \u2014 routers/ingest.py:325", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 routers/ingest.py:325"}, "fullDescription": {"text": "`requests.post(...)` 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-d785c17821858dcb", "name": "22 env vars used in code but missing from .env.example", "shortDescription": {"text": "22 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `AUTH_RATE_LIMIT_RPM`, `AWS_S3_BUCKET`, `DEMO_REQUESTS_ENABLED`, `DEMO_USER_PASSWORD`, `ENVIRONMENT`, `EXPORT_HMAC_SECRET`, `GUNICORN_WORKERS`, `HF_TOKEN` + 14 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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:\nschemas.py:text_not_whitespace, saro-data-framework/src/saro_data_framework/schema.py:text_not_blank\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:\nsaro-data-framework/src/saro_data_framework/converters/real_toxicity_prompts.py:download, saro-data-framework/src/saro_data_framework/converters/guardrails_hallucination.py:download, saro-data-framework/src/saro_data_framework/converters/pii_masking.py:download\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-b8c451e29c016341", "name": "Frontend route `/dashboard` has no Link/navigate to it \u2014 frontend/src/App.jsx", "shortDescription": {"text": "Frontend route `/dashboard` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "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-4284a30fae677783", "name": "FastAPI POST `saml_acs` without auth dependency \u2014 routers/sso.py:226", "shortDescription": {"text": "FastAPI POST `saml_acs` without auth dependency \u2014 routers/sso.py:226"}, "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-741cbd95be9d7e4d", "name": "FastAPI POST `magic_link_login` without auth dependency \u2014 routers/sso.py:386", "shortDescription": {"text": "FastAPI POST `magic_link_login` without auth dependency \u2014 routers/sso.py:386"}, "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-d60961efbfc24b9d", "name": "FastAPI POST `bootstrap` without auth dependency \u2014 routers/auth.py:43", "shortDescription": {"text": "FastAPI POST `bootstrap` without auth dependency \u2014 routers/auth.py:43"}, "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-f97807c41bfe2371", "name": "FastAPI POST `demo_signup` without auth dependency \u2014 routers/demo.py:42", "shortDescription": {"text": "FastAPI POST `demo_signup` without auth dependency \u2014 routers/demo.py:42"}, "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-4fc9fdc5ed7e2121", "name": "Dangling fetch: PATCH /api/v1/auth/users/${user.id}/persona?persona_role=${newPersona} (frontend/src/components/Sidebar.", "shortDescription": {"text": "Dangling fetch: PATCH /api/v1/auth/users/${user.id}/persona?persona_role=${newPersona} (frontend/src/components/Sidebar.jsx:119)"}, "fullDescription": {"text": "`frontend/src/components/Sidebar.jsx:119` calls `PATCH /api/v1/auth/users/${user.id}/persona?persona_role=${newPersona}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/users/<p>/persona`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7c80d21a30a53f31", "name": "Dangling fetch: GET /api/v1/rules/packs (frontend/src/pages/RulePacks.jsx:14)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/rules/packs (frontend/src/pages/RulePacks.jsx:14)"}, "fullDescription": {"text": "`frontend/src/pages/RulePacks.jsx:14` calls `GET /api/v1/rules/packs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/rules/packs`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-544ad8fedd86c8e0", "name": "Dangling fetch: GET /api/v1/compliance-matrix/summary (frontend/src/pages/ClaimsMatrix.jsx:30)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/compliance-matrix/summary (frontend/src/pages/ClaimsMatrix.jsx:30)"}, "fullDescription": {"text": "`frontend/src/pages/ClaimsMatrix.jsx:30` calls `GET /api/v1/compliance-matrix/summary` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/compliance-matrix/summary`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b964b625a56ae858", "name": "Dangling fetch: GET /api/v1/evaluations (frontend/src/pages/Evaluations.jsx:46)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/evaluations (frontend/src/pages/Evaluations.jsx:46)"}, "fullDescription": {"text": "`frontend/src/pages/Evaluations.jsx:46` calls `GET /api/v1/evaluations` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/evaluations`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-3a81e289e61f2e0d", "name": "Dangling fetch: POST /api/v1/evaluations/trigger (frontend/src/pages/Evaluations.jsx:69)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/evaluations/trigger (frontend/src/pages/Evaluations.jsx:69)"}, "fullDescription": {"text": "`frontend/src/pages/Evaluations.jsx:69` calls `POST /api/v1/evaluations/trigger` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/evaluations/trigger`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-338efabd5e3df350", "name": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/RiskRegister.jsx:50)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/RiskRegister.jsx:50)"}, "fullDescription": {"text": "`frontend/src/pages/RiskRegister.jsx:50` calls `GET /api/v1/risks` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risks`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a987b970f297bf24", "name": "Dangling fetch: POST /api/v1/risks/bulk (frontend/src/pages/RiskRegister.jsx:133)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/risks/bulk (frontend/src/pages/RiskRegister.jsx:133)"}, "fullDescription": {"text": "`frontend/src/pages/RiskRegister.jsx:133` calls `POST /api/v1/risks/bulk` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risks/bulk`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e3b707f8e5dd1092", "name": "Dangling fetch: DELETE /api/v1/risks/${deleteId} (frontend/src/pages/RiskRegister.jsx:161)", "shortDescription": {"text": "Dangling fetch: DELETE /api/v1/risks/${deleteId} (frontend/src/pages/RiskRegister.jsx:161)"}, "fullDescription": {"text": "`frontend/src/pages/RiskRegister.jsx:161` calls `DELETE /api/v1/risks/${deleteId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risks/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-dc5f55f0f354a66f", "name": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/RiskForm.jsx:35)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/RiskForm.jsx:35)"}, "fullDescription": {"text": "`frontend/src/pages/RiskForm.jsx:35` calls `GET /api/v1/risks` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risks`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-bfb8920917782ae4", "name": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/Reports.jsx:102)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/Reports.jsx:102)"}, "fullDescription": {"text": "`frontend/src/pages/Reports.jsx:102` calls `GET /api/v1/risks` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risks`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-b44244437f228843", "name": "Dangling fetch: GET /api/v1/audits?limit=10&sort=desc (frontend/src/pages/TraceView.jsx:54)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/audits?limit=10&sort=desc (frontend/src/pages/TraceView.jsx:54)"}, "fullDescription": {"text": "`frontend/src/pages/TraceView.jsx:54` calls `GET /api/v1/audits?limit=10&sort=desc` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/audits`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-59918b538707d5b3", "name": "Dangling fetch: GET /api/v1/traces/${target} (frontend/src/pages/TraceView.jsx:79)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/traces/${target} (frontend/src/pages/TraceView.jsx:79)"}, "fullDescription": {"text": "`frontend/src/pages/TraceView.jsx:79` calls `GET /api/v1/traces/${target}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/traces/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-9ac8417a989806da", "name": "Dangling fetch: GET /api/v1/audits/${target} (frontend/src/pages/TraceView.jsx:86)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/audits/${target} (frontend/src/pages/TraceView.jsx:86)"}, "fullDescription": {"text": "`frontend/src/pages/TraceView.jsx:86` calls `GET /api/v1/audits/${target}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/audits/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-10a3a678e9c3fc7a", "name": "Dangling fetch: GET /api/v1/governance/docs (frontend/src/pages/GovernanceDocs.jsx:21)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/governance/docs (frontend/src/pages/GovernanceDocs.jsx:21)"}, "fullDescription": {"text": "`frontend/src/pages/GovernanceDocs.jsx:21` calls `GET /api/v1/governance/docs` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/governance/docs`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-862af9c928ddf80b", "name": "Dangling fetch: GET /api/v1/governance/ir-plan (frontend/src/pages/GovernanceDocs.jsx:27)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/governance/ir-plan (frontend/src/pages/GovernanceDocs.jsx:27)"}, "fullDescription": {"text": "`frontend/src/pages/GovernanceDocs.jsx:27` calls `GET /api/v1/governance/ir-plan` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/governance/ir-plan`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-daa65be654b18b7f", "name": "Dangling fetch: GET /api/v1/risks/${riskId} (frontend/src/pages/RiskDetail.jsx:31)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/risks/${riskId} (frontend/src/pages/RiskDetail.jsx:31)"}, "fullDescription": {"text": "`frontend/src/pages/RiskDetail.jsx:31` calls `GET /api/v1/risks/${riskId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risks/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-04073f28b5c087de", "name": "Dangling fetch: GET /api/v1/traces/${auditId} (frontend/src/pages/RiskDetail.jsx:40)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/traces/${auditId} (frontend/src/pages/RiskDetail.jsx:40)"}, "fullDescription": {"text": "`frontend/src/pages/RiskDetail.jsx:40` calls `GET /api/v1/traces/${auditId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/traces/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-3b02746acb56c8e8", "name": "Dangling fetch: GET /api/v1/governance/trust-documents (frontend/src/pages/Governance.jsx:12)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/governance/trust-documents (frontend/src/pages/Governance.jsx:12)"}, "fullDescription": {"text": "`frontend/src/pages/Governance.jsx:12` calls `GET /api/v1/governance/trust-documents` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/governance/trust-documents`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e42a188d539a0116", "name": "Dangling fetch: PATCH /api/v1/remediation/${id}/complete (frontend/src/pages/Remediation.jsx:35)", "shortDescription": {"text": "Dangling fetch: PATCH /api/v1/remediation/${id}/complete (frontend/src/pages/Remediation.jsx:35)"}, "fullDescription": {"text": "`frontend/src/pages/Remediation.jsx:35` calls `PATCH /api/v1/remediation/${id}/complete` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/remediation/<p>/complete`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fb9aceeef9162837", "name": "Dangling fetch: GET /api/v1/rules/drift-alerts (frontend/src/pages/Dashboard.jsx:161)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/rules/drift-alerts (frontend/src/pages/Dashboard.jsx:161)"}, "fullDescription": {"text": "`frontend/src/pages/Dashboard.jsx:161` calls `GET /api/v1/rules/drift-alerts` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/rules/drift-alerts`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5d3ad97d33ff3777", "name": "Dangling fetch: GET /api/v1/risk/summary (frontend/src/pages/Dashboard.jsx:308)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/risk/summary (frontend/src/pages/Dashboard.jsx:308)"}, "fullDescription": {"text": "`frontend/src/pages/Dashboard.jsx:308` calls `GET /api/v1/risk/summary` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risk/summary`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-cf92150cd0049976", "name": "Dangling fetch: GET /api/v1/auth/users (frontend/src/pages/AdminSettings.jsx:35)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/auth/users (frontend/src/pages/AdminSettings.jsx:35)"}, "fullDescription": {"text": "`frontend/src/pages/AdminSettings.jsx:35` calls `GET /api/v1/auth/users` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/users`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-49075f8d9e4e050e", "name": "Dangling fetch: PATCH /api/v1/auth/users/${userId}/persona?persona_role=${persona} (frontend/src/pages/AdminSettings.jsx", "shortDescription": {"text": "Dangling fetch: PATCH /api/v1/auth/users/${userId}/persona?persona_role=${persona} (frontend/src/pages/AdminSettings.jsx:53)"}, "fullDescription": {"text": "`frontend/src/pages/AdminSettings.jsx:53` calls `PATCH /api/v1/auth/users/${userId}/persona?persona_role=${persona}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/users/<p>/persona`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e3e5d7b3f1f0566f", "name": "Dangling fetch: GET /api/v1/risk/board-export (frontend/src/pages/RiskSummary.jsx:67)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/risk/board-export (frontend/src/pages/RiskSummary.jsx:67)"}, "fullDescription": {"text": "`frontend/src/pages/RiskSummary.jsx:67` calls `GET /api/v1/risk/board-export` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/risk/board-export`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-eaf443c59815d318", "name": "Dangling fetch: GET /api/v1/audits?limit=30&sort=desc (frontend/src/pages/RiskSummary.jsx:108)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/audits?limit=30&sort=desc (frontend/src/pages/RiskSummary.jsx:108)"}, "fullDescription": {"text": "`frontend/src/pages/RiskSummary.jsx:108` calls `GET /api/v1/audits?limit=30&sort=desc` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/audits`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-f6321798586a0207", "name": "Dangling fetch: GET /api/v1/rules/drift-alerts (frontend/src/pages/DriftAlerts.jsx:13)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/rules/drift-alerts (frontend/src/pages/DriftAlerts.jsx:13)"}, "fullDescription": {"text": "`frontend/src/pages/DriftAlerts.jsx:13` calls `GET /api/v1/rules/drift-alerts` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/rules/drift-alerts`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-343d27dc7a0dacea", "name": "Dangling fetch: POST /api/v1/scan (frontend/src/pages/Upload.jsx:24)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/scan (frontend/src/pages/Upload.jsx:24)"}, "fullDescription": {"text": "`frontend/src/pages/Upload.jsx:24` calls `POST /api/v1/scan` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/scan`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e130f367179388aa", "name": "Dangling fetch: POST /api/v1/auth/token (frontend/src/pages/Login.jsx:75)", "shortDescription": {"text": "Dangling fetch: POST /api/v1/auth/token (frontend/src/pages/Login.jsx:75)"}, "fullDescription": {"text": "`frontend/src/pages/Login.jsx:75` calls `POST /api/v1/auth/token` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/token`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-61fafcfdc4cfe7b6", "name": "Dangling fetch: GET /api/v1/auth/me (frontend/src/pages/Login.jsx:101)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/auth/me (frontend/src/pages/Login.jsx:101)"}, "fullDescription": {"text": "`frontend/src/pages/Login.jsx:101` calls `GET /api/v1/auth/me` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/auth/me`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-cbfde09c7092f7ee", "name": "Dangling fetch: GET /api/v1/evf/status (frontend/src/pages/EvfAdmin.jsx:19)", "shortDescription": {"text": "Dangling fetch: GET /api/v1/evf/status (frontend/src/pages/EvfAdmin.jsx:19)"}, "fullDescription": {"text": "`frontend/src/pages/EvfAdmin.jsx:19` calls `GET /api/v1/evf/status` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/v1/evf/status`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`main.py` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1de80da0b27387f7", "name": "Unused endpoint: GET /unread-count", "shortDescription": {"text": "Unused endpoint: GET /unread-count"}, "fullDescription": {"text": "`routers/notifications.py` declares `GET /unread-count` 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-d9de08baca987ce0", "name": "Unused endpoint: PATCH /{notification_id}/read", "shortDescription": {"text": "Unused endpoint: PATCH /{notification_id}/read"}, "fullDescription": {"text": "`routers/notifications.py` declares `PATCH /{notification_id}/read` 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-f8d576f6bf0f5660", "name": "Unused endpoint: POST /read-all", "shortDescription": {"text": "Unused endpoint: POST /read-all"}, "fullDescription": {"text": "`routers/notifications.py` declares `POST /read-all` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-35a741079ddc6fcc", "name": "Unused endpoint: GET /stream", "shortDescription": {"text": "Unused endpoint: GET /stream"}, "fullDescription": {"text": "`routers/notifications.py` declares `GET /stream` 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-9803934c7082cfe9", "name": "Unused endpoint: POST /{audit_id}/export", "shortDescription": {"text": "Unused endpoint: POST /{audit_id}/export"}, "fullDescription": {"text": "`routers/trace_export.py` declares `POST /{audit_id}/export` 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-cf189ac2c95e6219", "name": "Unused endpoint: GET /{audit_id}/export.pdf", "shortDescription": {"text": "Unused endpoint: GET /{audit_id}/export.pdf"}, "fullDescription": {"text": "`routers/trace_export.py` declares `GET /{audit_id}/export.pdf` 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-3a5157384f529d5a", "name": "Unused endpoint: POST /{audit_id}/verify", "shortDescription": {"text": "Unused endpoint: POST /{audit_id}/verify"}, "fullDescription": {"text": "`routers/trace_export.py` declares `POST /{audit_id}/verify` 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-877af408e9f13305", "name": "Unused endpoint: PATCH /remediation/traces/{trace_id}/remediate", "shortDescription": {"text": "Unused endpoint: PATCH /remediation/traces/{trace_id}/remediate"}, "fullDescription": {"text": "`routers/remediation.py` declares `PATCH /remediation/traces/{trace_id}/remediate` 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-c1a3a32a5367ca31", "name": "Unused endpoint: POST /remediation/traces/{trace_id}/create-jira-issue", "shortDescription": {"text": "Unused endpoint: POST /remediation/traces/{trace_id}/create-jira-issue"}, "fullDescription": {"text": "`routers/remediation.py` declares `POST /remediation/traces/{trace_id}/create-jira-issue` 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-017f20d079b75899", "name": "Unused endpoint: GET /remediation/audits/{audit_id}/progress", "shortDescription": {"text": "Unused endpoint: GET /remediation/audits/{audit_id}/progress"}, "fullDescription": {"text": "`routers/remediation.py` declares `GET /remediation/audits/{audit_id}/progress` 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-ad205756fe1ea07f", "name": "Unused endpoint: GET /remediation/audits/{audit_id}/traces", "shortDescription": {"text": "Unused endpoint: GET /remediation/audits/{audit_id}/traces"}, "fullDescription": {"text": "`routers/remediation.py` declares `GET /remediation/audits/{audit_id}/traces` 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-d34ea8cbedb4ce29", "name": "Unused endpoint: GET /remediation/oauth/jira/start", "shortDescription": {"text": "Unused endpoint: GET /remediation/oauth/jira/start"}, "fullDescription": {"text": "`routers/remediation.py` declares `GET /remediation/oauth/jira/start` 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-1ac33c1c3891d353", "name": "Unused endpoint: GET /remediation/oauth/jira/callback", "shortDescription": {"text": "Unused endpoint: GET /remediation/oauth/jira/callback"}, "fullDescription": {"text": "`routers/remediation.py` declares `GET /remediation/oauth/jira/callback` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a9e986b14b03a6e8", "name": "Unused endpoint: GET /remediation", "shortDescription": {"text": "Unused endpoint: GET /remediation"}, "fullDescription": {"text": "`routers/remediation.py` declares `GET /remediation` 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-4c6219f3de75f651", "name": "Unused endpoint: POST /remediation/bulk-remediate", "shortDescription": {"text": "Unused endpoint: POST /remediation/bulk-remediate"}, "fullDescription": {"text": "`routers/remediation.py` declares `POST /remediation/bulk-remediate` 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-ef27df81b90eeb2e", "name": "Unused endpoint: POST /remediation/steps", "shortDescription": {"text": "Unused endpoint: POST /remediation/steps"}, "fullDescription": {"text": "`routers/remediation.py` declares `POST /remediation/steps` 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-ba9bee096fc9c270", "name": "Unused endpoint: POST /coverage/systems", "shortDescription": {"text": "Unused endpoint: POST /coverage/systems"}, "fullDescription": {"text": "`routers/remediation.py` declares `POST /coverage/systems` 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-6fc0caa269292c44", "name": "Unused endpoint: GET /coverage", "shortDescription": {"text": "Unused endpoint: GET /coverage"}, "fullDescription": {"text": "`routers/remediation.py` declares `GET /coverage` 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-67d28fa8cd6bb12f", "name": "Unused endpoint: PUT /", "shortDescription": {"text": "Unused endpoint: PUT /"}, "fullDescription": {"text": "`routers/risk_config.py` declares `PUT /` 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-3b30f4c0994a30b4", "name": "Unused endpoint: DELETE /", "shortDescription": {"text": "Unused endpoint: DELETE /"}, "fullDescription": {"text": "`routers/risk_config.py` declares `DELETE /` 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-e1b7bee247ffc801", "name": "Unused endpoint: GET /summary", "shortDescription": {"text": "Unused endpoint: GET /summary"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /summary` 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-91731fb32dd9b86a", "name": "Unused endpoint: GET /{audit_id}", "shortDescription": {"text": "Unused endpoint: GET /{audit_id}"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /{audit_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-32c5dc8d1e457dd4", "name": "Unused endpoint: GET /{audit_id}/mit", "shortDescription": {"text": "Unused endpoint: GET /{audit_id}/mit"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /{audit_id}/mit` 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-a99afd702becf851", "name": "Unused endpoint: GET /{audit_id}/delta", "shortDescription": {"text": "Unused endpoint: GET /{audit_id}/delta"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /{audit_id}/delta` 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-7bf8e75eb00f20cc", "name": "Unused endpoint: GET /{audit_id}/rules", "shortDescription": {"text": "Unused endpoint: GET /{audit_id}/rules"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /{audit_id}/rules` 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-cb701b98b97b0ba4", "name": "Unused endpoint: GET /{audit_id}/incidents", "shortDescription": {"text": "Unused endpoint: GET /{audit_id}/incidents"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /{audit_id}/incidents` 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-5b61ea490e29cbaa", "name": "Unused endpoint: GET /nist-coverage", "shortDescription": {"text": "Unused endpoint: GET /nist-coverage"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /nist-coverage` 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-455c607c09fdde8f", "name": "Unused endpoint: POST /{audit_id}/iso42001-annex", "shortDescription": {"text": "Unused endpoint: POST /{audit_id}/iso42001-annex"}, "fullDescription": {"text": "`routers/reports.py` declares `POST /{audit_id}/iso42001-annex` 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-756c2b514bdb4032", "name": "Unused endpoint: GET /engine/integrity", "shortDescription": {"text": "Unused endpoint: GET /engine/integrity"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /engine/integrity` 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-c38f893e8286bf5a", "name": "Unused endpoint: GET /incident-corpus-stats", "shortDescription": {"text": "Unused endpoint: GET /incident-corpus-stats"}, "fullDescription": {"text": "`routers/reports.py` declares `GET /incident-corpus-stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`routers/clients.py` declares `POST /` 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-33889608cd24af56", "name": "Unused endpoint: GET /{tenant_id}", "shortDescription": {"text": "Unused endpoint: GET /{tenant_id}"}, "fullDescription": {"text": "`routers/clients.py` declares `GET /{tenant_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-73654bbd8254768b", "name": "Unused endpoint: POST /{tenant_id}/test-sso", "shortDescription": {"text": "Unused endpoint: POST /{tenant_id}/test-sso"}, "fullDescription": {"text": "`routers/clients.py` declares `POST /{tenant_id}/test-sso` 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-a545ee816a07cae4", "name": "Unused endpoint: POST /{tenant_id}/scim/rotate-token", "shortDescription": {"text": "Unused endpoint: POST /{tenant_id}/scim/rotate-token"}, "fullDescription": {"text": "`routers/clients.py` declares `POST /{tenant_id}/scim/rotate-token` 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-db0a944118b068f6", "name": "Unused endpoint: POST /erasure-request", "shortDescription": {"text": "Unused endpoint: POST /erasure-request"}, "fullDescription": {"text": "`routers/governance.py` declares `POST /erasure-request` 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-6aaa484ef902281e", "name": "Unused endpoint: POST /retention-policy", "shortDescription": {"text": "Unused endpoint: POST /retention-policy"}, "fullDescription": {"text": "`routers/governance.py` declares `POST /retention-policy` 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-eb0428442a390121", "name": "Unused endpoint: GET /docs", "shortDescription": {"text": "Unused endpoint: GET /docs"}, "fullDescription": {"text": "`routers/governance.py` declares `GET /docs` 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-2f6ff363916a4b61", "name": "Unused endpoint: GET /ir-plan", "shortDescription": {"text": "Unused endpoint: GET /ir-plan"}, "fullDescription": {"text": "`routers/governance.py` declares `GET /ir-plan` 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-01d282a594c61679", "name": "Unused endpoint: GET /validation-status", "shortDescription": {"text": "Unused endpoint: GET /validation-status"}, "fullDescription": {"text": "`routers/evf_sprint3.py` declares `GET /validation-status` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5654a31e7a5b96b8", "name": "Unused endpoint: GET /validation-status/{framework}", "shortDescription": {"text": "Unused endpoint: GET /validation-status/{framework}"}, "fullDescription": {"text": "`routers/evf_sprint3.py` declares `GET /validation-status/{framework}` 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-6d2564e26f98da06", "name": "Unused endpoint: GET /qco/expiry-alerts", "shortDescription": {"text": "Unused endpoint: GET /qco/expiry-alerts"}, "fullDescription": {"text": "`routers/evf_sprint3.py` declares `GET /qco/expiry-alerts` 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-0a8002ab6a95d8d1", "name": "Unused endpoint: POST /admin/expiry-scan", "shortDescription": {"text": "Unused endpoint: POST /admin/expiry-scan"}, "fullDescription": {"text": "`routers/evf_sprint3.py` declares `POST /admin/expiry-scan` 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-f4fa03bbc02876b9", "name": "Unused endpoint: GET /verify-chain", "shortDescription": {"text": "Unused endpoint: GET /verify-chain"}, "fullDescription": {"text": "`routers/audit_chain.py` declares `GET /verify-chain` 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-41faee8f9b806963", "name": "Unused endpoint: GET /api/v1/sso/metadata/{tenant_slug}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/sso/metadata/{tenant_slug}"}, "fullDescription": {"text": "`routers/sso.py` declares `GET /api/v1/sso/metadata/{tenant_slug}` 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-b93e90f3b3f7c564", "name": "Unused endpoint: GET /api/v1/sso/login/{tenant_slug}", "shortDescription": {"text": "Unused endpoint: GET /api/v1/sso/login/{tenant_slug}"}, "fullDescription": {"text": "`routers/sso.py` declares `GET /api/v1/sso/login/{tenant_slug}` 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-8e23cd48c1ad6965", "name": "Unused endpoint: POST /api/v1/sso/acs/{tenant_slug}", "shortDescription": {"text": "Unused endpoint: POST /api/v1/sso/acs/{tenant_slug}"}, "fullDescription": {"text": "`routers/sso.py` declares `POST /api/v1/sso/acs/{tenant_slug}` 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-cbf0afc4f34924eb", "name": "Unused endpoint: POST /api/v1/sso/magic-link", "shortDescription": {"text": "Unused endpoint: POST /api/v1/sso/magic-link"}, "fullDescription": {"text": "`routers/sso.py` declares `POST /api/v1/sso/magic-link` 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-3929f317ee2031d0", "name": "Unused endpoint: GET /kpis", "shortDescription": {"text": "Unused endpoint: GET /kpis"}, "fullDescription": {"text": "`routers/dashboard.py` declares `GET /kpis` 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-144497972cf58e7c", "name": "Unused endpoint: GET /audits", "shortDescription": {"text": "Unused endpoint: GET /audits"}, "fullDescription": {"text": "`routers/dashboard.py` declares `GET /audits` 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/22138"}, "properties": {"repository": "venkybobby/SARO", "repoUrl": "https://github.com/venkybobby/SARO", "branch": "main"}, "results": [{"ruleId": "scanner-64f2788c30223bf6", "level": "note", "message": {"text": "Possibly dead Python function: require_write_access"}, "properties": {"repobilityId": "8773b1a08e43b4df", "scanner": "scanner-primary", "fingerprint": "64f2788c30223bf6", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "auth.py:198"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5162b06b5fdd5355", "level": "note", "message": {"text": "Possibly dead Python function: rules_for_domain"}, "properties": {"repobilityId": "7eec8959796ffa19", "scanner": "scanner-primary", "fingerprint": "5162b06b5fdd5355", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rule_packs/loader.py:79"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-0634fbd7aaae12d9", "level": "note", "message": {"text": "Possibly dead Python function: to_version_dict"}, "properties": {"repobilityId": "8d01369f39e890ac", "scanner": "scanner-primary", "fingerprint": "0634fbd7aaae12d9", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "rule_packs/loader.py:82"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c27c350ce482d2ee", "level": "note", "message": {"text": "Possibly dead Python function: create_issue"}, "properties": {"repobilityId": "d712aba803af65bd", "scanner": "scanner-primary", "fingerprint": "c27c350ce482d2ee", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "services/jira.py:33"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-24371b0d8515089a", "level": "note", "message": {"text": "Possibly dead Python function: dependency"}, "properties": {"repobilityId": "e2f97c76f5b6acb6", "scanner": "scanner-primary", "fingerprint": "24371b0d8515089a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "services/persona_service.py:171"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e86e9300aabb6319", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 frontend/src/App.jsx:163"}, "properties": {"repobilityId": "85eeae7d7006a85d", "scanner": "scanner-primary", "fingerprint": "e86e9300aabb6319", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-242d9bc09d95ac17", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/gen_fix_spec.js:2072"}, "properties": {"repobilityId": "d2526271b9652eb2", "scanner": "scanner-primary", "fingerprint": "242d9bc09d95ac17", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-e066691601852931", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "properties": {"repobilityId": "edb4dff8d5f82a2e", "scanner": "scanner-primary", "fingerprint": "e066691601852931", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-e066691601852931", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "properties": {"repobilityId": "bda1204f387897c0", "scanner": "scanner-primary", "fingerprint": "e066691601852931", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-60427b03771411b6", "level": "warning", "message": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "properties": {"repobilityId": "735c01d8531dfd2c", "scanner": "scanner-primary", "fingerprint": "60427b03771411b6", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "c08a18026d52fb0a", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-b048d166901fd868", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "properties": {"repobilityId": "c6e423b2899b5275", "scanner": "scanner-primary", "fingerprint": "b048d166901fd868", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-8750aff3566aef0a", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in main.py:117"}, "properties": {"repobilityId": "7efce937690fb5d6", "scanner": "scanner-primary", "fingerprint": "8750aff3566aef0a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "main.py"}, "region": {"startLine": 117}}}]}, {"ruleId": "scanner-550404e32a7a8d83", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in scripts/gen_fix_spec.js:1230"}, "properties": {"repobilityId": "d910edcac96fa0bd", "scanner": "scanner-primary", "fingerprint": "550404e32a7a8d83", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gen_fix_spec.js"}, "region": {"startLine": 1230}}}]}, {"ruleId": "scanner-49e41960b86672a6", "level": "warning", "message": {"text": "Insecure pattern 'weak_hash' in .claude/skills/security-audit/SKILL.md:30"}, "properties": {"repobilityId": "9d181d6d128d7943", "scanner": "scanner-primary", "fingerprint": "49e41960b86672a6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "weak_hash"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/security-audit/SKILL.md"}, "region": {"startLine": 30}}}]}, {"ruleId": "scanner-aa1c87f397d3e7bc", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "37ac699e65af438a", "scanner": "scanner-primary", "fingerprint": "aa1c87f397d3e7bc", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/eval-weekly.yml"}, "region": {"startLine": 99}}}]}, {"ruleId": "scanner-7f4a481c2e5a47e0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "d5c1028cbef19568", "scanner": "scanner-primary", "fingerprint": "7f4a481c2e5a47e0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-ci-fix.yml"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-7f4a481c2e5a47e0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "1e40798b7b9273ee", "scanner": "scanner-primary", "fingerprint": "7f4a481c2e5a47e0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-ci-fix.yml"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-7f4a481c2e5a47e0", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "f3ea2a1e9b03b74c", "scanner": "scanner-primary", "fingerprint": "7f4a481c2e5a47e0", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-ci-fix.yml"}, "region": {"startLine": 49}}}]}, {"ruleId": "scanner-7f4a481c2e5a47e0", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "fda293e2ef73e109", "scanner": "scanner-primary", "fingerprint": "7f4a481c2e5a47e0", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-ci-fix.yml"}, "region": {"startLine": 81}}}]}, {"ruleId": "scanner-dcd6030ad824412b", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "f1070b77d86a1b05", "scanner": "scanner-primary", "fingerprint": "dcd6030ad824412b", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-ci-fix.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5de4b45d2d113015", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "fe5859f2926cb59e", "scanner": "scanner-primary", "fingerprint": "5de4b45d2d113015", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-interactive.yml"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-5de4b45d2d113015", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a77eff51b06f4559", "scanner": "scanner-primary", "fingerprint": "5de4b45d2d113015", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-interactive.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-5de4b45d2d113015", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "626b9e9261c5896e", "scanner": "scanner-primary", "fingerprint": "5de4b45d2d113015", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-interactive.yml"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-5de4b45d2d113015", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a77eff51b06f4559", "scanner": "scanner-primary", "fingerprint": "5de4b45d2d113015", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-interactive.yml"}, "region": {"startLine": 78}}}]}, {"ruleId": "scanner-54d07f12537e2b32", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "56004628b72c2302", "scanner": "scanner-primary", "fingerprint": "54d07f12537e2b32", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-pr-review.yml"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-54d07f12537e2b32", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "f1bc0defa4f6560c", "scanner": "scanner-primary", "fingerprint": "54d07f12537e2b32", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-pr-review.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-75d0a1bf591f9323", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "1544d22c5c0b1841", "scanner": "scanner-primary", "fingerprint": "75d0a1bf591f9323", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-security-audit.yml"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-75d0a1bf591f9323", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "c58b4f98476620d2", "scanner": "scanner-primary", "fingerprint": "75d0a1bf591f9323", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-security-audit.yml"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-75d0a1bf591f9323", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8d5e08365da155b0", "scanner": "scanner-primary", "fingerprint": "75d0a1bf591f9323", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-security-audit.yml"}, "region": {"startLine": 74}}}]}, {"ruleId": "scanner-75d0a1bf591f9323", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "d5d5673db71ae695", "scanner": "scanner-primary", "fingerprint": "75d0a1bf591f9323", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/claude-security-audit.yml"}, "region": {"startLine": 143}}}]}, {"ruleId": "scanner-b2f6c3671667214f", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "263d3fe9723c8a39", "scanner": "scanner-primary", "fingerprint": "b2f6c3671667214f", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/security-evidence-weekly.yml"}, "region": {"startLine": 39}}}]}, {"ruleId": "scanner-3a99783390a92e1b", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "618c9af045894ac5", "scanner": "scanner-primary", "fingerprint": "3a99783390a92e1b", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/security-evidence-weekly.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ecd9dba21ccdc4fb", "level": "note", "message": {"text": "Very large file: engine.py (2053 lines)"}, "properties": {"repobilityId": "76defd1a7e06900f", "scanner": "scanner-primary", "fingerprint": "ecd9dba21ccdc4fb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-19881c9dec8a10e7", "level": "note", "message": {"text": "Very large file: models.py (1185 lines)"}, "properties": {"repobilityId": "f9d250461a08d929", "scanner": "scanner-primary", "fingerprint": "19881c9dec8a10e7", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-58e80cf96b7d399c", "level": "note", "message": {"text": "Very large file: scripts/gen_fix_spec.js (2075 lines)"}, "properties": {"repobilityId": "38765b5a612b533e", "scanner": "scanner-primary", "fingerprint": "58e80cf96b7d399c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "6e29255364c03197", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "c7c5411b2a505b81", "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": "ae267a418c63c2b2", "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": "00175c7f64d25185", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "edb5428bcdb4bf06", "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": "6f5560b3b221f79a", "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": "7dfe7e97bd96e654", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-19f18bdc1ea8040d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/agents/security-auditor.md"}, "properties": {"repobilityId": "41fc5f6dc929e898", "scanner": "scanner-primary", "fingerprint": "19f18bdc1ea8040d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/agents/security-auditor.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fb401590f323bf07", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: .claude/skills/deploy-railway/SKILL.md"}, "properties": {"repobilityId": "5375beba235b27f2", "scanner": "scanner-primary", "fingerprint": "fb401590f323bf07", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/deploy-railway/SKILL.md"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-4d95dbaa3da5907d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/rule-pack-edit/SKILL.md"}, "properties": {"repobilityId": "a6bcbcaa6aa6ee02", "scanner": "scanner-primary", "fingerprint": "4d95dbaa3da5907d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/rule-pack-edit/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-861199178aa5eb94", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/security-audit/SKILL.md"}, "properties": {"repobilityId": "51baefa98eeec622", "scanner": "scanner-primary", "fingerprint": "861199178aa5eb94", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/security-audit/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-68984449f3a63b77", "level": "none", "message": {"text": "Commented-code block (5 lines) in database.py:43"}, "properties": {"repobilityId": "997426d52cf00c86", "scanner": "scanner-primary", "fingerprint": "68984449f3a63b77", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6af7d03e03662bb9", "level": "none", "message": {"text": "Commented-code block (5 lines) in conftest.py:63"}, "properties": {"repobilityId": "cb4ead87321f6925", "scanner": "scanner-primary", "fingerprint": "6af7d03e03662bb9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f78c60312a33a574", "level": "none", "message": {"text": "Commented-code block (5 lines) in auth.py:58"}, "properties": {"repobilityId": "9315e01a3b2beca6", "scanner": "scanner-primary", "fingerprint": "f78c60312a33a574", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cb797ee2a0006355", "level": "none", "message": {"text": "Commented-code block (5 lines) in models.py:253"}, "properties": {"repobilityId": "8fc2155cd3f9fd7f", "scanner": "scanner-primary", "fingerprint": "cb797ee2a0006355", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f9f03c34b023aee6", "level": "none", "message": {"text": "Commented-code block (5 lines) in main.py:151"}, "properties": {"repobilityId": "d542504abf48d6a8", "scanner": "scanner-primary", "fingerprint": "f9f03c34b023aee6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-05bc82825b72d005", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api/saro.js:15"}, "properties": {"repobilityId": "f4bab5f495de43f5", "scanner": "scanner-primary", "fingerprint": "05bc82825b72d005", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1e3f97a3c66e1d05", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskForm.jsx:35"}, "properties": {"repobilityId": "e341a3e8896c7639", "scanner": "scanner-primary", "fingerprint": "1e3f97a3c66e1d05", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-db7593bf4c63445d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/ComplianceHub.jsx:23"}, "properties": {"repobilityId": "c1edd073667a6d4b", "scanner": "scanner-primary", "fingerprint": "db7593bf4c63445d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e718f7283a47b933", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/DemoEntry.jsx:21"}, "properties": {"repobilityId": "140f8fbea93ae205", "scanner": "scanner-primary", "fingerprint": "e718f7283a47b933", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-baee9046cc8b9cd3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskDetail.jsx:40"}, "properties": {"repobilityId": "aae44831f819cce8", "scanner": "scanner-primary", "fingerprint": "baee9046cc8b9cd3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-21af158fcbfac943", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/pages/RiskSummary.jsx:94"}, "properties": {"repobilityId": "1343bbba7ac09e61", "scanner": "scanner-primary", "fingerprint": "21af158fcbfac943", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4a8a39e6265742a5", "level": "note", "message": {"text": "Legacy-named symbol `nist_rmf_v1` in tests/test_gap2_notifications.py:122"}, "properties": {"repobilityId": "5ab4036fde7c788a", "scanner": "scanner-primary", "fingerprint": "4a8a39e6265742a5", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-c1c2aea2f8728d5b", "level": "none", "message": {"text": "Commented-code block (5 lines) in tests/test_epic6_security.py:119"}, "properties": {"repobilityId": "3f428096f4eeaa16", "scanner": "scanner-primary", "fingerprint": "c1c2aea2f8728d5b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-56b6dcaea8e2365e", "level": "note", "message": {"text": "Legacy-named symbol `test_no_unqualified_nist_aligned_claims_in_product_copy` in tests/test_pt007_nist_coverage.py:52"}, "properties": {"repobilityId": "ed6f8718e517ddbc", "scanner": "scanner-primary", "fingerprint": "56b6dcaea8e2365e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f5a41fb3e48752ed", "level": "note", "message": {"text": "Legacy-named symbol `nist_rmf_v1` in tests/test_epic4_rule_packs.py:55"}, "properties": {"repobilityId": "09bf793c875af498", "scanner": "scanner-primary", "fingerprint": "f5a41fb3e48752ed", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-e2f85339c84b9b0a", "level": "none", "message": {"text": "Commented-code block (7 lines) in tests/test_epic4_rule_packs.py:110"}, "properties": {"repobilityId": "f9323916a20f853a", "scanner": "scanner-primary", "fingerprint": "e2f85339c84b9b0a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a7b593e04681a7ac", "level": "none", "message": {"text": "Commented-code block (5 lines) in middleware/rate_limiter.py:28"}, "properties": {"repobilityId": "f32ad509721725b4", "scanner": "scanner-primary", "fingerprint": "a7b593e04681a7ac", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-069a825d53e599da", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 scripts/update_quality_baseline.py:20"}, "properties": {"repobilityId": "e86457af349da087", "scanner": "scanner-primary", "fingerprint": "069a825d53e599da", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6f9b99c08f4e4b59", "level": "note", "message": {"text": "Legacy-named symbol `SARO_Fix_Spec_v1` in scripts/gen_fix_spec.js:4"}, "properties": {"repobilityId": "b5c771bc57d075c9", "scanner": "scanner-primary", "fingerprint": "6f9b99c08f4e4b59", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-d318482a32037448", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 scripts/gen_fix_spec.js:1165"}, "properties": {"repobilityId": "cf016f4d5fc0bd52", "scanner": "scanner-primary", "fingerprint": "d318482a32037448", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3354e196643a644b", "level": "none", "message": {"text": "Commented-code block (8 lines) in saro-data-framework/src/saro_data/converters/guardrails_hallucination.py:30"}, "properties": {"repobilityId": "b7934a1a5cda563a", "scanner": "scanner-primary", "fingerprint": "3354e196643a644b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-65c519476857dfc4", "level": "none", "message": {"text": "Commented-code block (8 lines) in services/evf_qco_service.py:325"}, "properties": {"repobilityId": "c3780ebd19448605", "scanner": "scanner-primary", "fingerprint": "65c519476857dfc4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bf37ac2e096ac8e8", "level": "note", "message": {"text": "Legacy-named symbol `partial_legacy` in routers/audit_chain.py:95"}, "properties": {"repobilityId": "97ed828f2b5d41cf", "scanner": "scanner-primary", "fingerprint": "bf37ac2e096ac8e8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8e9bb5c2027ea02b", "level": "none", "message": {"text": "Commented-code block (5 lines) in routers/sso.py:45"}, "properties": {"repobilityId": "a673f1a940fdc070", "scanner": "scanner-primary", "fingerprint": "8e9bb5c2027ea02b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5f59c108e846922f", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 routers/ingest.py:325"}, "properties": {"repobilityId": "2f08adb4dfc0040e", "scanner": "scanner-primary", "fingerprint": "5f59c108e846922f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d785c17821858dcb", "level": "note", "message": {"text": "22 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "f5222babac44ad42", "scanner": "scanner-primary", "fingerprint": "d785c17821858dcb", "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": "d85176cb24d1ba17", "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": "ac5f11166c7ec297", "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": "a92d537e95ef0b7e", "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": "73dd1c7632772039", "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": "2e1a2debecd95c16", "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": "724c5d8c1938f56f", "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": "f4d785d3a7dcd59f", "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": "950ee82ef1c5ff9a", "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": "de7e186caa1b2130", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-b8c451e29c016341", "level": "warning", "message": {"text": "Frontend route `/dashboard` has no Link/navigate to it \u2014 frontend/src/App.jsx"}, "properties": {"repobilityId": "39e8f296c574f9a4", "scanner": "scanner-primary", "fingerprint": "b8c451e29c016341", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-4284a30fae677783", "level": "error", "message": {"text": "FastAPI POST `saml_acs` without auth dependency \u2014 routers/sso.py:226"}, "properties": {"repobilityId": "79499f3e99dc8ec6", "scanner": "scanner-primary", "fingerprint": "4284a30fae677783", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "routers/sso.py"}, "region": {"startLine": 226}}}]}, {"ruleId": "scanner-741cbd95be9d7e4d", "level": "error", "message": {"text": "FastAPI POST `magic_link_login` without auth dependency \u2014 routers/sso.py:386"}, "properties": {"repobilityId": "345c4413d6eceda6", "scanner": "scanner-primary", "fingerprint": "741cbd95be9d7e4d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "routers/sso.py"}, "region": {"startLine": 386}}}]}, {"ruleId": "scanner-d60961efbfc24b9d", "level": "error", "message": {"text": "FastAPI POST `bootstrap` without auth dependency \u2014 routers/auth.py:43"}, "properties": {"repobilityId": "d6587f2b774702d0", "scanner": "scanner-primary", "fingerprint": "d60961efbfc24b9d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "routers/auth.py"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-f97807c41bfe2371", "level": "error", "message": {"text": "FastAPI POST `demo_signup` without auth dependency \u2014 routers/demo.py:42"}, "properties": {"repobilityId": "3940a0bfb9e20eac", "scanner": "scanner-primary", "fingerprint": "f97807c41bfe2371", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "routers/demo.py"}, "region": {"startLine": 42}}}]}, {"ruleId": "scanner-4fc9fdc5ed7e2121", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/v1/auth/users/${user.id}/persona?persona_role=${newPersona} (frontend/src/components/Sidebar.jsx:119)"}, "properties": {"repobilityId": "a049ce3ac0434174", "scanner": "scanner-primary", "fingerprint": "4fc9fdc5ed7e2121", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7c80d21a30a53f31", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/rules/packs (frontend/src/pages/RulePacks.jsx:14)"}, "properties": {"repobilityId": "e621247a091a8eed", "scanner": "scanner-primary", "fingerprint": "7c80d21a30a53f31", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-544ad8fedd86c8e0", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/compliance-matrix/summary (frontend/src/pages/ClaimsMatrix.jsx:30)"}, "properties": {"repobilityId": "4f18ea365fe73607", "scanner": "scanner-primary", "fingerprint": "544ad8fedd86c8e0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b964b625a56ae858", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/evaluations (frontend/src/pages/Evaluations.jsx:46)"}, "properties": {"repobilityId": "6d9ef2b0220b6d22", "scanner": "scanner-primary", "fingerprint": "b964b625a56ae858", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3a81e289e61f2e0d", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/evaluations/trigger (frontend/src/pages/Evaluations.jsx:69)"}, "properties": {"repobilityId": "e7331018e593a376", "scanner": "scanner-primary", "fingerprint": "3a81e289e61f2e0d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-338efabd5e3df350", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/RiskRegister.jsx:50)"}, "properties": {"repobilityId": "1a219ac9fac59797", "scanner": "scanner-primary", "fingerprint": "338efabd5e3df350", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a987b970f297bf24", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/risks/bulk (frontend/src/pages/RiskRegister.jsx:133)"}, "properties": {"repobilityId": "4c194ef0e94e5c9e", "scanner": "scanner-primary", "fingerprint": "a987b970f297bf24", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e3b707f8e5dd1092", "level": "error", "message": {"text": "Dangling fetch: DELETE /api/v1/risks/${deleteId} (frontend/src/pages/RiskRegister.jsx:161)"}, "properties": {"repobilityId": "f6d4574f20364611", "scanner": "scanner-primary", "fingerprint": "e3b707f8e5dd1092", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-dc5f55f0f354a66f", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/RiskForm.jsx:35)"}, "properties": {"repobilityId": "5e2239b5b34e2dd1", "scanner": "scanner-primary", "fingerprint": "dc5f55f0f354a66f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-bfb8920917782ae4", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/risks (frontend/src/pages/Reports.jsx:102)"}, "properties": {"repobilityId": "6b1f285669f5f1c6", "scanner": "scanner-primary", "fingerprint": "bfb8920917782ae4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b44244437f228843", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/audits?limit=10&sort=desc (frontend/src/pages/TraceView.jsx:54)"}, "properties": {"repobilityId": "0e41566c02b65bdc", "scanner": "scanner-primary", "fingerprint": "b44244437f228843", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-59918b538707d5b3", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/traces/${target} (frontend/src/pages/TraceView.jsx:79)"}, "properties": {"repobilityId": "6c7497a5bd9b1342", "scanner": "scanner-primary", "fingerprint": "59918b538707d5b3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9ac8417a989806da", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/audits/${target} (frontend/src/pages/TraceView.jsx:86)"}, "properties": {"repobilityId": "357a6068a15de5bf", "scanner": "scanner-primary", "fingerprint": "9ac8417a989806da", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-10a3a678e9c3fc7a", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/governance/docs (frontend/src/pages/GovernanceDocs.jsx:21)"}, "properties": {"repobilityId": "120278ee32118b83", "scanner": "scanner-primary", "fingerprint": "10a3a678e9c3fc7a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-862af9c928ddf80b", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/governance/ir-plan (frontend/src/pages/GovernanceDocs.jsx:27)"}, "properties": {"repobilityId": "9bbed58859fff40d", "scanner": "scanner-primary", "fingerprint": "862af9c928ddf80b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-daa65be654b18b7f", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/risks/${riskId} (frontend/src/pages/RiskDetail.jsx:31)"}, "properties": {"repobilityId": "02d73924dcfba7d7", "scanner": "scanner-primary", "fingerprint": "daa65be654b18b7f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-04073f28b5c087de", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/traces/${auditId} (frontend/src/pages/RiskDetail.jsx:40)"}, "properties": {"repobilityId": "bab112efc44e4e29", "scanner": "scanner-primary", "fingerprint": "04073f28b5c087de", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3b02746acb56c8e8", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/governance/trust-documents (frontend/src/pages/Governance.jsx:12)"}, "properties": {"repobilityId": "3e56612a0e118d9c", "scanner": "scanner-primary", "fingerprint": "3b02746acb56c8e8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e42a188d539a0116", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/v1/remediation/${id}/complete (frontend/src/pages/Remediation.jsx:35)"}, "properties": {"repobilityId": "9096bee2fbadb8fd", "scanner": "scanner-primary", "fingerprint": "e42a188d539a0116", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fb9aceeef9162837", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/rules/drift-alerts (frontend/src/pages/Dashboard.jsx:161)"}, "properties": {"repobilityId": "4f617e9c2d6c7979", "scanner": "scanner-primary", "fingerprint": "fb9aceeef9162837", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5d3ad97d33ff3777", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/risk/summary (frontend/src/pages/Dashboard.jsx:308)"}, "properties": {"repobilityId": "041b15be074d345a", "scanner": "scanner-primary", "fingerprint": "5d3ad97d33ff3777", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-cf92150cd0049976", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/auth/users (frontend/src/pages/AdminSettings.jsx:35)"}, "properties": {"repobilityId": "eed3e808a4cdbb7c", "scanner": "scanner-primary", "fingerprint": "cf92150cd0049976", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-49075f8d9e4e050e", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/v1/auth/users/${userId}/persona?persona_role=${persona} (frontend/src/pages/AdminSettings.jsx:53)"}, "properties": {"repobilityId": "889651046fd3a37d", "scanner": "scanner-primary", "fingerprint": "49075f8d9e4e050e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e3e5d7b3f1f0566f", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/risk/board-export (frontend/src/pages/RiskSummary.jsx:67)"}, "properties": {"repobilityId": "93662c0c5cd1c1a1", "scanner": "scanner-primary", "fingerprint": "e3e5d7b3f1f0566f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-eaf443c59815d318", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/audits?limit=30&sort=desc (frontend/src/pages/RiskSummary.jsx:108)"}, "properties": {"repobilityId": "0a8b03ddc2b389c2", "scanner": "scanner-primary", "fingerprint": "eaf443c59815d318", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f6321798586a0207", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/rules/drift-alerts (frontend/src/pages/DriftAlerts.jsx:13)"}, "properties": {"repobilityId": "c8500ccebb1c66e3", "scanner": "scanner-primary", "fingerprint": "f6321798586a0207", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-343d27dc7a0dacea", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/scan (frontend/src/pages/Upload.jsx:24)"}, "properties": {"repobilityId": "94ae914618c5cfee", "scanner": "scanner-primary", "fingerprint": "343d27dc7a0dacea", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e130f367179388aa", "level": "error", "message": {"text": "Dangling fetch: POST /api/v1/auth/token (frontend/src/pages/Login.jsx:75)"}, "properties": {"repobilityId": "b114df401f7e7cf0", "scanner": "scanner-primary", "fingerprint": "e130f367179388aa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-61fafcfdc4cfe7b6", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/auth/me (frontend/src/pages/Login.jsx:101)"}, "properties": {"repobilityId": "4efa1d24bbcad1d9", "scanner": "scanner-primary", "fingerprint": "61fafcfdc4cfe7b6", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-cbfde09c7092f7ee", "level": "error", "message": {"text": "Dangling fetch: GET /api/v1/evf/status (frontend/src/pages/EvfAdmin.jsx:19)"}, "properties": {"repobilityId": "50875157838680ee", "scanner": "scanner-primary", "fingerprint": "cbfde09c7092f7ee", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "6b8de433dc23649f", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1de80da0b27387f7", "level": "note", "message": {"text": "Unused endpoint: GET /unread-count"}, "properties": {"repobilityId": "c3d529f7e41a0f6f", "scanner": "scanner-primary", "fingerprint": "1de80da0b27387f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d9de08baca987ce0", "level": "note", "message": {"text": "Unused endpoint: PATCH /{notification_id}/read"}, "properties": {"repobilityId": "b3b45c1d981a713d", "scanner": "scanner-primary", "fingerprint": "d9de08baca987ce0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f8d576f6bf0f5660", "level": "note", "message": {"text": "Unused endpoint: POST /read-all"}, "properties": {"repobilityId": "ce5a934ce77c820f", "scanner": "scanner-primary", "fingerprint": "f8d576f6bf0f5660", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-35a741079ddc6fcc", "level": "note", "message": {"text": "Unused endpoint: GET /stream"}, "properties": {"repobilityId": "e3217761cfca58a2", "scanner": "scanner-primary", "fingerprint": "35a741079ddc6fcc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9803934c7082cfe9", "level": "note", "message": {"text": "Unused endpoint: POST /{audit_id}/export"}, "properties": {"repobilityId": "4cf7e289c8b6e5c6", "scanner": "scanner-primary", "fingerprint": "9803934c7082cfe9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cf189ac2c95e6219", "level": "note", "message": {"text": "Unused endpoint: GET /{audit_id}/export.pdf"}, "properties": {"repobilityId": "c5a19df900f9256d", "scanner": "scanner-primary", "fingerprint": "cf189ac2c95e6219", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3a5157384f529d5a", "level": "note", "message": {"text": "Unused endpoint: POST /{audit_id}/verify"}, "properties": {"repobilityId": "98f8fee233457ecf", "scanner": "scanner-primary", "fingerprint": "3a5157384f529d5a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-877af408e9f13305", "level": "note", "message": {"text": "Unused endpoint: PATCH /remediation/traces/{trace_id}/remediate"}, "properties": {"repobilityId": "14af1a33a9ae7c05", "scanner": "scanner-primary", "fingerprint": "877af408e9f13305", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c1a3a32a5367ca31", "level": "note", "message": {"text": "Unused endpoint: POST /remediation/traces/{trace_id}/create-jira-issue"}, "properties": {"repobilityId": "84421642ef01ebe6", "scanner": "scanner-primary", "fingerprint": "c1a3a32a5367ca31", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-017f20d079b75899", "level": "note", "message": {"text": "Unused endpoint: GET /remediation/audits/{audit_id}/progress"}, "properties": {"repobilityId": "3d60deba2f1a7c44", "scanner": "scanner-primary", "fingerprint": "017f20d079b75899", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ad205756fe1ea07f", "level": "note", "message": {"text": "Unused endpoint: GET /remediation/audits/{audit_id}/traces"}, "properties": {"repobilityId": "8405a7ab9c09d48f", "scanner": "scanner-primary", "fingerprint": "ad205756fe1ea07f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d34ea8cbedb4ce29", "level": "note", "message": {"text": "Unused endpoint: GET /remediation/oauth/jira/start"}, "properties": {"repobilityId": "38aa0d05f869f897", "scanner": "scanner-primary", "fingerprint": "d34ea8cbedb4ce29", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ac33c1c3891d353", "level": "note", "message": {"text": "Unused endpoint: GET /remediation/oauth/jira/callback"}, "properties": {"repobilityId": "b81bd7df16d46faa", "scanner": "scanner-primary", "fingerprint": "1ac33c1c3891d353", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a9e986b14b03a6e8", "level": "note", "message": {"text": "Unused endpoint: GET /remediation"}, "properties": {"repobilityId": "cb6470f508417a1f", "scanner": "scanner-primary", "fingerprint": "a9e986b14b03a6e8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4c6219f3de75f651", "level": "note", "message": {"text": "Unused endpoint: POST /remediation/bulk-remediate"}, "properties": {"repobilityId": "02f852b1dc89add2", "scanner": "scanner-primary", "fingerprint": "4c6219f3de75f651", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ef27df81b90eeb2e", "level": "note", "message": {"text": "Unused endpoint: POST /remediation/steps"}, "properties": {"repobilityId": "d399090b7f08962b", "scanner": "scanner-primary", "fingerprint": "ef27df81b90eeb2e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ba9bee096fc9c270", "level": "note", "message": {"text": "Unused endpoint: POST /coverage/systems"}, "properties": {"repobilityId": "df835b98d72878d5", "scanner": "scanner-primary", "fingerprint": "ba9bee096fc9c270", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6fc0caa269292c44", "level": "note", "message": {"text": "Unused endpoint: GET /coverage"}, "properties": {"repobilityId": "316007886b9ca2fe", "scanner": "scanner-primary", "fingerprint": "6fc0caa269292c44", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-67d28fa8cd6bb12f", "level": "note", "message": {"text": "Unused endpoint: PUT /"}, "properties": {"repobilityId": "5f73603223b1e17d", "scanner": "scanner-primary", "fingerprint": "67d28fa8cd6bb12f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b30f4c0994a30b4", "level": "note", "message": {"text": "Unused endpoint: DELETE /"}, "properties": {"repobilityId": "4f43013a6204da9f", "scanner": "scanner-primary", "fingerprint": "3b30f4c0994a30b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e1b7bee247ffc801", "level": "note", "message": {"text": "Unused endpoint: GET /summary"}, "properties": {"repobilityId": "be63a70d08ba410c", "scanner": "scanner-primary", "fingerprint": "e1b7bee247ffc801", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-91731fb32dd9b86a", "level": "note", "message": {"text": "Unused endpoint: GET /{audit_id}"}, "properties": {"repobilityId": "36d61b6a6ccde417", "scanner": "scanner-primary", "fingerprint": "91731fb32dd9b86a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-32c5dc8d1e457dd4", "level": "note", "message": {"text": "Unused endpoint: GET /{audit_id}/mit"}, "properties": {"repobilityId": "6b965c7387f2ff77", "scanner": "scanner-primary", "fingerprint": "32c5dc8d1e457dd4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a99afd702becf851", "level": "note", "message": {"text": "Unused endpoint: GET /{audit_id}/delta"}, "properties": {"repobilityId": "42c3f395129cdd51", "scanner": "scanner-primary", "fingerprint": "a99afd702becf851", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7bf8e75eb00f20cc", "level": "note", "message": {"text": "Unused endpoint: GET /{audit_id}/rules"}, "properties": {"repobilityId": "65a2cf143400c80b", "scanner": "scanner-primary", "fingerprint": "7bf8e75eb00f20cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cb701b98b97b0ba4", "level": "note", "message": {"text": "Unused endpoint: GET /{audit_id}/incidents"}, "properties": {"repobilityId": "3cc8993a022f6866", "scanner": "scanner-primary", "fingerprint": "cb701b98b97b0ba4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5b61ea490e29cbaa", "level": "note", "message": {"text": "Unused endpoint: GET /nist-coverage"}, "properties": {"repobilityId": "5a48dda70c92bb12", "scanner": "scanner-primary", "fingerprint": "5b61ea490e29cbaa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-455c607c09fdde8f", "level": "note", "message": {"text": "Unused endpoint: POST /{audit_id}/iso42001-annex"}, "properties": {"repobilityId": "0f2acb7a291d7e7f", "scanner": "scanner-primary", "fingerprint": "455c607c09fdde8f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-756c2b514bdb4032", "level": "note", "message": {"text": "Unused endpoint: GET /engine/integrity"}, "properties": {"repobilityId": "d9aad6d3ca45bafa", "scanner": "scanner-primary", "fingerprint": "756c2b514bdb4032", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c38f893e8286bf5a", "level": "note", "message": {"text": "Unused endpoint: GET /incident-corpus-stats"}, "properties": {"repobilityId": "7ef313854eb7f058", "scanner": "scanner-primary", "fingerprint": "c38f893e8286bf5a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "0ac97519b6d1a6b7", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-33889608cd24af56", "level": "note", "message": {"text": "Unused endpoint: GET /{tenant_id}"}, "properties": {"repobilityId": "8b3fb4260d99f70d", "scanner": "scanner-primary", "fingerprint": "33889608cd24af56", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-73654bbd8254768b", "level": "note", "message": {"text": "Unused endpoint: POST /{tenant_id}/test-sso"}, "properties": {"repobilityId": "4638f98e00213138", "scanner": "scanner-primary", "fingerprint": "73654bbd8254768b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a545ee816a07cae4", "level": "note", "message": {"text": "Unused endpoint: POST /{tenant_id}/scim/rotate-token"}, "properties": {"repobilityId": "844a83e3917427a8", "scanner": "scanner-primary", "fingerprint": "a545ee816a07cae4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-db0a944118b068f6", "level": "note", "message": {"text": "Unused endpoint: POST /erasure-request"}, "properties": {"repobilityId": "58584e68548c98a4", "scanner": "scanner-primary", "fingerprint": "db0a944118b068f6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6aaa484ef902281e", "level": "note", "message": {"text": "Unused endpoint: POST /retention-policy"}, "properties": {"repobilityId": "87882dccf25b04a6", "scanner": "scanner-primary", "fingerprint": "6aaa484ef902281e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eb0428442a390121", "level": "note", "message": {"text": "Unused endpoint: GET /docs"}, "properties": {"repobilityId": "38f70565d0f097c9", "scanner": "scanner-primary", "fingerprint": "eb0428442a390121", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2f6ff363916a4b61", "level": "note", "message": {"text": "Unused endpoint: GET /ir-plan"}, "properties": {"repobilityId": "da171afcb788f7e5", "scanner": "scanner-primary", "fingerprint": "2f6ff363916a4b61", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-01d282a594c61679", "level": "note", "message": {"text": "Unused endpoint: GET /validation-status"}, "properties": {"repobilityId": "5bd06d9983e85f00", "scanner": "scanner-primary", "fingerprint": "01d282a594c61679", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5654a31e7a5b96b8", "level": "note", "message": {"text": "Unused endpoint: GET /validation-status/{framework}"}, "properties": {"repobilityId": "b448cf0bf608ce06", "scanner": "scanner-primary", "fingerprint": "5654a31e7a5b96b8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6d2564e26f98da06", "level": "note", "message": {"text": "Unused endpoint: GET /qco/expiry-alerts"}, "properties": {"repobilityId": "abd23e80d47fbfac", "scanner": "scanner-primary", "fingerprint": "6d2564e26f98da06", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0a8002ab6a95d8d1", "level": "note", "message": {"text": "Unused endpoint: POST /admin/expiry-scan"}, "properties": {"repobilityId": "87e96ff7f7220392", "scanner": "scanner-primary", "fingerprint": "0a8002ab6a95d8d1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f4fa03bbc02876b9", "level": "note", "message": {"text": "Unused endpoint: GET /verify-chain"}, "properties": {"repobilityId": "f9a78104abcc28fe", "scanner": "scanner-primary", "fingerprint": "f4fa03bbc02876b9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41faee8f9b806963", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/sso/metadata/{tenant_slug}"}, "properties": {"repobilityId": "bbf6b4df781155a7", "scanner": "scanner-primary", "fingerprint": "41faee8f9b806963", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b93e90f3b3f7c564", "level": "note", "message": {"text": "Unused endpoint: GET /api/v1/sso/login/{tenant_slug}"}, "properties": {"repobilityId": "4c6eb225e39cf331", "scanner": "scanner-primary", "fingerprint": "b93e90f3b3f7c564", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e23cd48c1ad6965", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/sso/acs/{tenant_slug}"}, "properties": {"repobilityId": "0f819f6b88069947", "scanner": "scanner-primary", "fingerprint": "8e23cd48c1ad6965", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cbf0afc4f34924eb", "level": "note", "message": {"text": "Unused endpoint: POST /api/v1/sso/magic-link"}, "properties": {"repobilityId": "5086e0601f976ee9", "scanner": "scanner-primary", "fingerprint": "cbf0afc4f34924eb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3929f317ee2031d0", "level": "note", "message": {"text": "Unused endpoint: GET /kpis"}, "properties": {"repobilityId": "19f5b8e6e7bf9dad", "scanner": "scanner-primary", "fingerprint": "3929f317ee2031d0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-144497972cf58e7c", "level": "note", "message": {"text": "Unused endpoint: GET /audits"}, "properties": {"repobilityId": "45067e2c2a86ed8a", "scanner": "scanner-primary", "fingerprint": "144497972cf58e7c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}