{"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-08e1b72043fa9673", "name": "Possibly dead Python function: wrap_text", "shortDescription": {"text": "Possibly dead Python function: wrap_text"}, "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-f3a0637236fb4392", "name": "Possibly dead Python function: do_activate", "shortDescription": {"text": "Possibly dead Python function: do_activate"}, "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-efb3f79e169602a6", "name": "Possibly dead Python function: do_download", "shortDescription": {"text": "Possibly dead Python function: do_download"}, "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-c5e50e2b93070059", "name": "Possibly dead Python function: worker", "shortDescription": {"text": "Possibly dead Python function: worker"}, "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-b1c586ba8335003f", "name": "Possibly dead Python function: worker", "shortDescription": {"text": "Possibly dead Python function: worker"}, "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-b7bf764670c20066", "name": "Possibly dead Python function: show_with_text", "shortDescription": {"text": "Possibly dead Python function: show_with_text"}, "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-fe63013f5fb47e33", "name": "Possibly dead Python function: is_x11", "shortDescription": {"text": "Possibly dead Python function: is_x11"}, "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-2565b57546347ef3", "name": "Possibly dead Python function: refresh_session", "shortDescription": {"text": "Possibly dead Python function: refresh_session"}, "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-d5fffb31368e0efc", "name": "Possibly dead Python function: load", "shortDescription": {"text": "Possibly dead Python function: load"}, "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-007c3faaf24f8757", "name": "Possibly dead Python function: set_auto_start", "shortDescription": {"text": "Possibly dead Python function: set_auto_start"}, "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-0992302356fad742", "name": "Possibly dead Python function: report_handled", "shortDescription": {"text": "Possibly dead Python function: report_handled"}, "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-0952c647754fe5a1", "name": "Icon-only button without accessible name \u2014 admin/src/components/Toast.tsx:62", "shortDescription": {"text": "Icon-only button without accessible name \u2014 admin/src/components/Toast.tsx:62"}, "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-c00876fc9ff3f8a8", "name": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/InboxPage.tsx:173", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/InboxPage.tsx:173"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e66c4a60af037fec", "name": "React Flow edge with `label=` but no project-wide edge-label CSS override \u2014 admin/src/pages/BugReportsPage.tsx:58", "shortDescription": {"text": "React Flow edge with `label=` but no project-wide edge-label CSS override \u2014 admin/src/pages/BugReportsPage.tsx:58"}, "fullDescription": {"text": "React Flow edge labels render with a white rectangle behind the text by default, which scatters bright boxes across a dark canvas. Either drop the label, or override `.react-flow__edge-textbg` and `.react-flow__edge-text` in your stylesheet.\n\nWhy: P-H in CHECKLIST.md \u2014 vendor edge labels bleed white through a dark canvas.\nRule id: fq.edge-label.no-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b70928277edadd14", "name": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/ErrorsPage.tsx:266", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/ErrorsPage.tsx:266"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c9fb7f9ec9043be5", "name": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/VersionsPage.tsx:276", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/VersionsPage.tsx:276"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3173a49e9cb9a7b3", "name": "Stray `console.log` in TS/JS \u2014 admin/e2e/report-bug.spec.ts:55", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 admin/e2e/report-bug.spec.ts:55"}, "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-f7a2fa03f3c90977", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/generate-openapi.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/generate-openapi.ts:33"}, "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-800a10d8a1ed7932", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/sync-stripe-prices.js:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/sync-stripe-prices.js:25"}, "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-963a5f21014519b6", "name": "Stray `console.log` in TS/JS \u2014 backend/scripts/sync-stripe-prices.ts:62", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/sync-stripe-prices.ts:62"}, "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-10c2e549741ae56a", "name": "Stray `console.log` in TS/JS \u2014 backend/src/seed.ts:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/seed.ts:29"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-93f44c5abc40a016", "name": "Stray `console.log` in TS/JS \u2014 backend/src/main.ts:59", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/main.ts:59"}, "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-c3446b178b7d8286", "name": "Dockerfile runs as root: admin/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: admin/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-6edc7d50d68a358c", "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-097f08ff98e759d4", "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-1f66ad88286ca30a", "name": "Dockerfile runs as root: backend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: backend/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-3d2a6283f9ebab24", "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-3ceed35c3ef0e2e4", "name": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-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-9661a3f2c0b88853", "name": "Docker base image is tag-pinned but not digest-pinned: gcr.io/distroless/static-debian12:nonroot", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: gcr.io/distroless/static-debian12:nonroot"}, "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-acc4597922133411", "name": "Runtime dotenv file present in repo: admin/.env.production", "shortDescription": {"text": "Runtime dotenv file present in repo: admin/.env.production"}, "fullDescription": {"text": "`admin/.env.production` looks like a runtime dotenv file. No high-confidence secret value was matched, but runtime dotenv files often drift into live credentials. Move real values to a secret manager and keep only `.env.example` style templates in source control."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-43247045256bd19d", "name": "Possible secret in scripts/test-linux-api-smoke.py", "shortDescription": {"text": "Possible secret in scripts/test-linux-api-smoke.py"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-b99a6494f302fb3e", "name": "Insecure pattern 'local_storage_auth_token' in website/src/components/Checkout.tsx:186", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/components/Checkout.tsx:186"}, "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-02b40ce713a72816", "name": "Insecure pattern 'local_storage_auth_token' in website/src/components/LoginForm.tsx:30", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/components/LoginForm.tsx:30"}, "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-a3a514b724cf6c72", "name": "Insecure pattern 'local_storage_auth_token' in website/src/components/SignupForm.tsx:35", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/components/SignupForm.tsx:35"}, "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-72de1a0bb1f7ad21", "name": "Insecure pattern 'local_storage_auth_token' in website/src/lib/socialAuth.ts:87", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/lib/socialAuth.ts:87"}, "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-60895657d1281dc6", "name": "Insecure pattern 'local_storage_auth_token' in admin/src/auth.ts:22", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in admin/src/auth.ts:22"}, "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-63ace385acde3b59", "name": "Possible secret in admin/e2e/report-bug.spec.ts", "shortDescription": {"text": "Possible secret in admin/e2e/report-bug.spec.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-ce670926e37f82b9", "name": "Possible secret in backend/test/integration/auth-login.int-spec.ts", "shortDescription": {"text": "Possible secret in backend/test/integration/auth-login.int-spec.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-d5afed38e7e042e1", "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-360cb263256aacfa", "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@v6 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-6e61fb60af308a45", "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-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 92 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 139 placeholder/mock markers across 48 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-bea357a6497a2d5d", "name": "Agent authority lacks a verifier contract: CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: CLAUDE.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-9917d6c3e8dde0f1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/AccountPage.tsx:117", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/AccountPage.tsx:117"}, "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-dc686e3864022e0a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/SuggestFeatureWidget.tsx:53", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/SuggestFeatureWidget.tsx:53"}, "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-f302c83682007ad0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/FeedbackBoard.tsx:227", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/FeedbackBoard.tsx:227"}, "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-f5095092b1d1ec3c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/Playground.tsx:83", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/Playground.tsx:83"}, "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-b4ba902855cd33ad", "name": "Commented-code block (7 lines) in DraftRightLinux/draftright/application.py:61", "shortDescription": {"text": "Commented-code block (7 lines) in DraftRightLinux/draftright/application.py:61"}, "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-aa0eee5a7c38eaed", "name": "Legacy-named symbol `_on_copy` in DraftRightLinux/draftright/ui/checkout_dialogs.py:184", "shortDescription": {"text": "Legacy-named symbol `_on_copy` in DraftRightLinux/draftright/ui/checkout_dialogs.py:184"}, "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-e36fe614b4ebcec9", "name": "Commented-code block (5 lines) in DraftRightLinux/draftright/ui/settings_window.py:137", "shortDescription": {"text": "Commented-code block (5 lines) in DraftRightLinux/draftright/ui/settings_window.py:137"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-81002bf243ac9b14", "name": "Network/subprocess call without timeout or try/except \u2014 DraftRightLinux/draftright/ui/settings_window.py:461", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 DraftRightLinux/draftright/ui/settings_window.py:461"}, "fullDescription": {"text": "`subprocess.Popen(...)` 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-0eb8acd587f197bc", "name": "Legacy-named symbol `on_copy` in DraftRightLinux/draftright/ui/rewrite_panel.py:257", "shortDescription": {"text": "Legacy-named symbol `on_copy` in DraftRightLinux/draftright/ui/rewrite_panel.py:257"}, "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-91f158e3718aee02", "name": "Legacy-named symbol `_simulate_copy` in DraftRightLinux/draftright/services/clipboard_service.py:69", "shortDescription": {"text": "Legacy-named symbol `_simulate_copy` in DraftRightLinux/draftright/services/clipboard_service.py:69"}, "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-fcf160235c8ba92e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/api.ts:8", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/api.ts:8"}, "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-126323862150897c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/pages/BugReportsPage.tsx:90", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/pages/BugReportsPage.tsx:90"}, "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-af83dd37434b42aa", "name": "Commented-code block (5 lines) in backend/scripts/sync-stripe-prices.ts:110", "shortDescription": {"text": "Commented-code block (5 lines) in backend/scripts/sync-stripe-prices.ts: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-6361fc820086e021", "name": "Commented-code block (5 lines) in backend/src/config/env.schema.ts:83", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/config/env.schema.ts:83"}, "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-e02c8a47ed52a36b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/auth/auth.service.ts:368", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/auth/auth.service.ts:368"}, "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-346df93ca5513988", "name": "Commented-code block (7 lines) in backend/src/health/health.controller.ts:10", "shortDescription": {"text": "Commented-code block (7 lines) in backend/src/health/health.controller.ts:10"}, "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-6439d04bd1f2f67d", "name": "Commented-code block (5 lines) in backend/src/common/all-exceptions.filter.ts:84", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/common/all-exceptions.filter.ts:84"}, "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-6f08cd76ce2b4a8a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/lemonsqueezy/lemonsqueezy.service.ts:58", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/lemonsqueezy/lemonsqueezy.service.ts:58"}, "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-4d8b907aceec73fd", "name": "Commented-code block (9 lines) in backend/src/ime-packs/dto/language-module.dto.ts:1", "shortDescription": {"text": "Commented-code block (9 lines) in backend/src/ime-packs/dto/language-module.dto.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-34ccae2c10ee4bad", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/ai-providers/strategies/openai.strategy.ts:48", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/ai-providers/strategies/openai.strategy.ts:48"}, "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-56915c46631f2afc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/ai-providers/strategies/anthropic.strategy.ts:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/ai-providers/strategies/anthropic.strategy.ts:38"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1a6c62c863188e63", "name": "Commented-code block (5 lines) in backend/src/errors/fix-proposal.cron.ts:44", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/errors/fix-proposal.cron.ts:44"}, "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-718a5272b61cd85d", "name": "Commented-code block (5 lines) in backend/src/admin/entities/app-settings.entity.ts:129", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/admin/entities/app-settings.entity.ts:129"}, "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-bd12c4dd374940b7", "name": "Commented-code block (5 lines) in backend/src/bug-reports/bug-reports.controller.ts:15", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/bug-reports/bug-reports.controller.ts:15"}, "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-e0f9ac87a4d41e27", "name": "Commented-code block (5 lines) in backend/src/bug-reports/dto/create-bug-report.dto.ts:15", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/bug-reports/dto/create-bug-report.dto.ts:15"}, "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-3aba5a4315841660", "name": "Commented-code block (5 lines) in backend/src/payment/payment.service.ts:56", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/payment/payment.service.ts:56"}, "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-71660ec869f4929a", "name": "Commented-code block (5 lines) in backend/src/payment/payment.controller.ts:66", "shortDescription": {"text": "Commented-code block (5 lines) in backend/src/payment/payment.controller.ts:66"}, "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-4d15c910041b4572", "name": "Commented-code block (9 lines) in backend/src/payment/strategies/vietqr.strategy.ts:46", "shortDescription": {"text": "Commented-code block (9 lines) in backend/src/payment/strategies/vietqr.strategy.ts:46"}, "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-5195cb7d564785eb", "name": "Commented-code block (10 lines) in backend/src/payment/strategies/lemonsqueezy.strategy.ts:107", "shortDescription": {"text": "Commented-code block (10 lines) in backend/src/payment/strategies/lemonsqueezy.strategy.ts:107"}, "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-473ec117e95613d5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/payment/strategies/lemonsqueezy.strategy.ts:127", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/payment/strategies/lemonsqueezy.strategy.ts:127"}, "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-d3455c0658e85742", "name": "Commented-code block (7 lines) in backend/src/payment/strategies/stripe.strategy.ts:67", "shortDescription": {"text": "Commented-code block (7 lines) in backend/src/payment/strategies/stripe.strategy.ts:67"}, "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-a60963cd4adc0c90", "name": "Commented-code block (6 lines) in backend/src/payment/strategies/payment-strategy.interface.ts:63", "shortDescription": {"text": "Commented-code block (6 lines) in backend/src/payment/strategies/payment-strategy.interface.ts: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-7c8b918e1fee9558", "name": "20 env vars used in code but missing from .env.example", "shortDescription": {"text": "20 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BACKEND_URL`, `DISPLAY`, `DRAFTRIGHT_BACKEND_URL`, `GDK_BACKEND`, `GO_BACKEND_RAMP_PERCENT`, `LANG`, `NODE_ENV`, `OTEL_EXPORTER_OTLP_ENDPOINT` + 12 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-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nscripts/seed-keyboard-multi-ios-test-cases.py:main, scripts/seed-single-instance-test-cases.py:main, scripts/seed-keyboard-multi-test-cases.py:main\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-49c98f7cedd9c977", "name": "Near-duplicate function bodies in 4 places", "shortDescription": {"text": "Near-duplicate function bodies in 4 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nDraftRightLinux/draftright/services/payment_service.py:kind, DraftRightLinux/draftright/services/payment_service.py:kind, DraftRightLinux/draftright/services/payment_service.py:kind, DraftRightLinux/draftright/services/payment_service.py:kind\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nDraftRightLinux/draftright/services/settings_service.py:backend_url, DraftRightLinux/draftright/services/settings_service.py:backend_url\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-1aff11349402159e", "name": "Frontend route `/users/:id` has no Link/navigate to it \u2014 admin/src/App.tsx", "shortDescription": {"text": "Frontend route `/users/:id` has no Link/navigate to it \u2014 admin/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e7e5ccdbbd6e308f", "name": "Dangling fetch: GET https://oauth2.googleapis.com/tokeninfo?id_token=${idToken} (backend/src/auth/auth.service.ts:368)", "shortDescription": {"text": "Dangling fetch: GET https://oauth2.googleapis.com/tokeninfo?id_token=${idToken} (backend/src/auth/auth.service.ts:368)"}, "fullDescription": {"text": "`backend/src/auth/auth.service.ts:368` calls `GET https://oauth2.googleapis.com/tokeninfo?id_token=${idToken}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/oauth2.googleapis.com/tokeninfo`\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-fdfedccd0a77ced3", "name": "Dangling fetch: GET https://appleid.apple.com/auth/keys (backend/src/auth/auth.service.ts:464)", "shortDescription": {"text": "Dangling fetch: GET https://appleid.apple.com/auth/keys (backend/src/auth/auth.service.ts:464)"}, "fullDescription": {"text": "`backend/src/auth/auth.service.ts:464` calls `GET https://appleid.apple.com/auth/keys` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/appleid.apple.com/auth/keys`\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-8a2ffb301cffe6a4", "name": "Dangling fetch: GET https://graph.facebook.com/me?fields=id,name,email,picture.type(large)&access_token=${accessToken} (", "shortDescription": {"text": "Dangling fetch: GET https://graph.facebook.com/me?fields=id,name,email,picture.type(large)&access_token=${accessToken} (backend/src/auth/auth.service.ts:485)"}, "fullDescription": {"text": "`backend/src/auth/auth.service.ts:485` calls `GET https://graph.facebook.com/me?fields=id,name,email,picture.type(large)&access_token=${accessToken}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/graph.facebook.com/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-1c4176e167f6b167", "name": "Dangling fetch: DELETE https://api.lemonsqueezy.com/v1/customers/${user.lemonsqueezy_customer_id} (backend/src/payment/s", "shortDescription": {"text": "Dangling fetch: DELETE https://api.lemonsqueezy.com/v1/customers/${user.lemonsqueezy_customer_id} (backend/src/payment/strategies/lemonsqueezy.strategy.ts:161)"}, "fullDescription": {"text": "`backend/src/payment/strategies/lemonsqueezy.strategy.ts:161` calls `DELETE https://api.lemonsqueezy.com/v1/customers/${user.lemonsqueezy_customer_id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.lemonsqueezy.com/v1/customers/<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-8292c0931391749a", "name": "Unused endpoint: POST /auth/register", "shortDescription": {"text": "Unused endpoint: POST /auth/register"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8fdbacfe9430a6ed", "name": "Unused endpoint: POST /auth/login", "shortDescription": {"text": "Unused endpoint: POST /auth/login"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b36892106ecdc9aa", "name": "Unused endpoint: POST /auth/refresh", "shortDescription": {"text": "Unused endpoint: POST /auth/refresh"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/refresh` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ccadf58fea366726", "name": "Unused endpoint: POST /auth/verify-email", "shortDescription": {"text": "Unused endpoint: POST /auth/verify-email"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/verify-email` 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-ff5660488b9ce2ca", "name": "Unused endpoint: POST /auth/resend-verification", "shortDescription": {"text": "Unused endpoint: POST /auth/resend-verification"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/resend-verification` 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-e2fe5b92648ca462", "name": "Unused endpoint: POST /auth/forgot-password", "shortDescription": {"text": "Unused endpoint: POST /auth/forgot-password"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/forgot-password` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-deb8df763a50c73a", "name": "Unused endpoint: POST /auth/reset-password", "shortDescription": {"text": "Unused endpoint: POST /auth/reset-password"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/reset-password` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b977f7cf742075a3", "name": "Unused endpoint: POST /auth/social", "shortDescription": {"text": "Unused endpoint: POST /auth/social"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/social` 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-4585c350da9e880d", "name": "Unused endpoint: POST /auth/change-password", "shortDescription": {"text": "Unused endpoint: POST /auth/change-password"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `POST /auth/change-password` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ac42422b23e45104", "name": "Unused endpoint: GET /auth/me", "shortDescription": {"text": "Unused endpoint: GET /auth/me"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `GET /auth/me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2346b4b4a8d305f0", "name": "Unused endpoint: DELETE /auth/account", "shortDescription": {"text": "Unused endpoint: DELETE /auth/account"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `DELETE /auth/account` 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-b0b32589fd24b5ed", "name": "Unused endpoint: GET /auth/account", "shortDescription": {"text": "Unused endpoint: GET /auth/account"}, "fullDescription": {"text": "`backend/src/auth/auth.controller.ts` declares `GET /auth/account` 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-7e85a54b2b112eb8", "name": "Unused endpoint: DELETE /auth/extension-tokens/:id", "shortDescription": {"text": "Unused endpoint: DELETE /auth/extension-tokens/:id"}, "fullDescription": {"text": "`backend/src/auth/extension-token.controller.ts` declares `DELETE /auth/extension-tokens/: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-b0aa2de383afa1ce", "name": "Unused endpoint: POST /lemonsqueezy/checkout", "shortDescription": {"text": "Unused endpoint: POST /lemonsqueezy/checkout"}, "fullDescription": {"text": "`backend/src/lemonsqueezy/lemonsqueezy.controller.ts` declares `POST /lemonsqueezy/checkout` 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-3197f6861ed09dd7", "name": "Unused endpoint: GET /lemonsqueezy/portal", "shortDescription": {"text": "Unused endpoint: GET /lemonsqueezy/portal"}, "fullDescription": {"text": "`backend/src/lemonsqueezy/lemonsqueezy.controller.ts` declares `GET /lemonsqueezy/portal` 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-56639343c9df2d5b", "name": "Unused endpoint: POST /lemonsqueezy/webhook", "shortDescription": {"text": "Unused endpoint: POST /lemonsqueezy/webhook"}, "fullDescription": {"text": "`backend/src/lemonsqueezy/lemonsqueezy.controller.ts` declares `POST /lemonsqueezy/webhook` 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-a80f0b102431958c", "name": "Unused endpoint: GET /updates/latest", "shortDescription": {"text": "Unused endpoint: GET /updates/latest"}, "fullDescription": {"text": "`backend/src/updates/updates.controller.ts` declares `GET /updates/latest` 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-8ab86be72ab70aae", "name": "Unused endpoint: GET /ime-packs/manifest", "shortDescription": {"text": "Unused endpoint: GET /ime-packs/manifest"}, "fullDescription": {"text": "`backend/src/ime-packs/ime-packs.controller.ts` declares `GET /ime-packs/manifest` 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-9d592078c7e35e6d", "name": "Unused endpoint: GET /admin/bug-reports", "shortDescription": {"text": "Unused endpoint: GET /admin/bug-reports"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/bug-reports` 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-2c46eaf6c1b323d2", "name": "Unused endpoint: GET /admin/bug-reports/:id", "shortDescription": {"text": "Unused endpoint: GET /admin/bug-reports/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/bug-reports/: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-5dd022fbb457a43d", "name": "Unused endpoint: GET /admin/bug-reports/:id/screenshot", "shortDescription": {"text": "Unused endpoint: GET /admin/bug-reports/:id/screenshot"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/bug-reports/:id/screenshot` 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-3c66c0ba020991fc", "name": "Unused endpoint: PATCH /admin/bug-reports/:id", "shortDescription": {"text": "Unused endpoint: PATCH /admin/bug-reports/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `PATCH /admin/bug-reports/: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-6b503549bccf8b29", "name": "Unused endpoint: DELETE /admin/bug-reports/:id", "shortDescription": {"text": "Unused endpoint: DELETE /admin/bug-reports/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `DELETE /admin/bug-reports/: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-c1c08f1cc647f314", "name": "Unused endpoint: POST /admin/bug-reports/:id/fix-proposal", "shortDescription": {"text": "Unused endpoint: POST /admin/bug-reports/:id/fix-proposal"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/bug-reports/:id/fix-proposal` 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-05d1d28f4f1f49ed", "name": "Unused endpoint: GET /admin/inbox/counts", "shortDescription": {"text": "Unused endpoint: GET /admin/inbox/counts"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/inbox/counts` 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-0fbcff8d1eca53cc", "name": "Unused endpoint: GET /admin/inbox", "shortDescription": {"text": "Unused endpoint: GET /admin/inbox"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/inbox` 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-0400039c6249f60b", "name": "Unused endpoint: GET /admin/errors", "shortDescription": {"text": "Unused endpoint: GET /admin/errors"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/errors` 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-cdfb9c96d94f098a", "name": "Unused endpoint: GET /admin/errors/:id", "shortDescription": {"text": "Unused endpoint: GET /admin/errors/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/errors/: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-fddac3b91a26c420", "name": "Unused endpoint: PATCH /admin/errors/:id", "shortDescription": {"text": "Unused endpoint: PATCH /admin/errors/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `PATCH /admin/errors/: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-8e3ea8b261adbbbd", "name": "Unused endpoint: DELETE /admin/errors/:id", "shortDescription": {"text": "Unused endpoint: DELETE /admin/errors/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `DELETE /admin/errors/: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-64f833f2bc745a75", "name": "Unused endpoint: POST /admin/errors/:id/suggest-fix", "shortDescription": {"text": "Unused endpoint: POST /admin/errors/:id/suggest-fix"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/errors/:id/suggest-fix` 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-6b067d028514918e", "name": "Unused endpoint: POST /admin/errors/run-ai-cron", "shortDescription": {"text": "Unused endpoint: POST /admin/errors/run-ai-cron"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/errors/run-ai-cron` 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-66acf2ed6319dc66", "name": "Unused endpoint: GET /admin/releases", "shortDescription": {"text": "Unused endpoint: GET /admin/releases"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/releases` 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-992661aa1ae3985c", "name": "Unused endpoint: POST /admin/releases", "shortDescription": {"text": "Unused endpoint: POST /admin/releases"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/releases` 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-ebb446f1a1695458", "name": "Unused endpoint: DELETE /admin/releases/:platform/:channel", "shortDescription": {"text": "Unused endpoint: DELETE /admin/releases/:platform/:channel"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `DELETE /admin/releases/:platform/:channel` 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-1fa15bd78bce54cf", "name": "Unused endpoint: POST /admin/release-policies", "shortDescription": {"text": "Unused endpoint: POST /admin/release-policies"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/release-policies` 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-233109e646627809", "name": "Unused endpoint: GET /admin/email-logs", "shortDescription": {"text": "Unused endpoint: GET /admin/email-logs"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/email-logs` 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-7127a9563bb17fbc", "name": "Unused endpoint: GET /admin/email-templates", "shortDescription": {"text": "Unused endpoint: GET /admin/email-templates"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/email-templates` 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-b309bf002a5dc943", "name": "Unused endpoint: PATCH /admin/email-templates/:key", "shortDescription": {"text": "Unused endpoint: PATCH /admin/email-templates/:key"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `PATCH /admin/email-templates/:key` 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-433d547eccb1ae7e", "name": "Unused endpoint: DELETE /admin/email-templates/:key", "shortDescription": {"text": "Unused endpoint: DELETE /admin/email-templates/:key"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `DELETE /admin/email-templates/:key` 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-1a41cb602c21e715", "name": "Unused endpoint: GET /admin/email-templates/:key/preview", "shortDescription": {"text": "Unused endpoint: GET /admin/email-templates/:key/preview"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/email-templates/:key/preview` 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-e2ad6d44231b81ad", "name": "Unused endpoint: GET /admin/settings", "shortDescription": {"text": "Unused endpoint: GET /admin/settings"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-967a1069385a4354", "name": "Unused endpoint: PATCH /admin/settings", "shortDescription": {"text": "Unused endpoint: PATCH /admin/settings"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `PATCH /admin/settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9ac44a67d38fe1f1", "name": "Unused endpoint: POST /admin/settings/test-email", "shortDescription": {"text": "Unused endpoint: POST /admin/settings/test-email"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/settings/test-email` 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-dd159bd05997c05c", "name": "Unused endpoint: GET /admin/stats", "shortDescription": {"text": "Unused endpoint: GET /admin/stats"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/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-0aba7f1883cb96f2", "name": "Unused endpoint: GET /admin/users", "shortDescription": {"text": "Unused endpoint: GET /admin/users"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/users` 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-3bb3ff08475b5e3e", "name": "Unused endpoint: GET /admin/users/:id", "shortDescription": {"text": "Unused endpoint: GET /admin/users/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/users/: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-f24cea56cd2023a1", "name": "Unused endpoint: PATCH /admin/users/:id", "shortDescription": {"text": "Unused endpoint: PATCH /admin/users/:id"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `PATCH /admin/users/: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-2273ac666d251484", "name": "Unused endpoint: GET /admin/plans", "shortDescription": {"text": "Unused endpoint: GET /admin/plans"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `GET /admin/plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-922eccd4e86b578d", "name": "Unused endpoint: POST /admin/plans", "shortDescription": {"text": "Unused endpoint: POST /admin/plans"}, "fullDescription": {"text": "`backend/src/admin/admin.controller.ts` declares `POST /admin/plans` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/20827"}, "properties": {"repository": "tannpv/draftright", "repoUrl": "https://github.com/tannpv/draftright", "branch": "main"}, "results": [{"ruleId": "scanner-08e1b72043fa9673", "level": "note", "message": {"text": "Possibly dead Python function: wrap_text"}, "properties": {"repobilityId": "622a0694f386965e", "scanner": "scanner-primary", "fingerprint": "08e1b72043fa9673", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gen-screenshots.py:76"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f3a0637236fb4392", "level": "note", "message": {"text": "Possibly dead Python function: do_activate"}, "properties": {"repobilityId": "c2840318fe37d0f3", "scanner": "scanner-primary", "fingerprint": "f3a0637236fb4392", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/application.py:55"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-efb3f79e169602a6", "level": "note", "message": {"text": "Possibly dead Python function: do_download"}, "properties": {"repobilityId": "94aa7b39b793074d", "scanner": "scanner-primary", "fingerprint": "efb3f79e169602a6", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/application.py:349"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c5e50e2b93070059", "level": "note", "message": {"text": "Possibly dead Python function: worker"}, "properties": {"repobilityId": "fbe2b50200068803", "scanner": "scanner-primary", "fingerprint": "c5e50e2b93070059", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/ui/suggest_feature_dialog.py:154"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b1c586ba8335003f", "level": "note", "message": {"text": "Possibly dead Python function: worker"}, "properties": {"repobilityId": "fbe2b50200068803", "scanner": "scanner-primary", "fingerprint": "b1c586ba8335003f", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/ui/subscription_page.py:237"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b7bf764670c20066", "level": "note", "message": {"text": "Possibly dead Python function: show_with_text"}, "properties": {"repobilityId": "8d147ec1fc07a477", "scanner": "scanner-primary", "fingerprint": "b7bf764670c20066", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/ui/rewrite_panel.py:272"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fe63013f5fb47e33", "level": "note", "message": {"text": "Possibly dead Python function: is_x11"}, "properties": {"repobilityId": "ea24309958f6fa68", "scanner": "scanner-primary", "fingerprint": "fe63013f5fb47e33", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/helpers/display_server.py:11"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2565b57546347ef3", "level": "note", "message": {"text": "Possibly dead Python function: refresh_session"}, "properties": {"repobilityId": "845750644a85f424", "scanner": "scanner-primary", "fingerprint": "2565b57546347ef3", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/services/auth_service.py:174"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d5fffb31368e0efc", "level": "note", "message": {"text": "Possibly dead Python function: load"}, "properties": {"repobilityId": "eadc4c9cffbfdd85", "scanner": "scanner-primary", "fingerprint": "d5fffb31368e0efc", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/services/settings_service.py:156"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-007c3faaf24f8757", "level": "note", "message": {"text": "Possibly dead Python function: set_auto_start"}, "properties": {"repobilityId": "2986b7edbc6cfc37", "scanner": "scanner-primary", "fingerprint": "007c3faaf24f8757", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/services/settings_service.py:184"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-0992302356fad742", "level": "note", "message": {"text": "Possibly dead Python function: report_handled"}, "properties": {"repobilityId": "98745c3442fb9a47", "scanner": "scanner-primary", "fingerprint": "0992302356fad742", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightLinux/draftright/services/error_reporter.py:76"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-0952c647754fe5a1", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 admin/src/components/Toast.tsx:62"}, "properties": {"repobilityId": "0d66f3e1a821fed5", "scanner": "scanner-primary", "fingerprint": "0952c647754fe5a1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-c00876fc9ff3f8a8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/InboxPage.tsx:173"}, "properties": {"repobilityId": "797ddc2572300251", "scanner": "scanner-primary", "fingerprint": "c00876fc9ff3f8a8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e66c4a60af037fec", "level": "note", "message": {"text": "React Flow edge with `label=` but no project-wide edge-label CSS override \u2014 admin/src/pages/BugReportsPage.tsx:58"}, "properties": {"repobilityId": "87c44a4fb01f0bea", "scanner": "scanner-primary", "fingerprint": "e66c4a60af037fec", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.edge-label.no-bg"]}}, {"ruleId": "scanner-b70928277edadd14", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/ErrorsPage.tsx:266"}, "properties": {"repobilityId": "aec30babc97ea08c", "scanner": "scanner-primary", "fingerprint": "b70928277edadd14", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c9fb7f9ec9043be5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 admin/src/pages/VersionsPage.tsx:276"}, "properties": {"repobilityId": "7db1877355358a5c", "scanner": "scanner-primary", "fingerprint": "c9fb7f9ec9043be5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3173a49e9cb9a7b3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 admin/e2e/report-bug.spec.ts:55"}, "properties": {"repobilityId": "6a35385ba45c5d4e", "scanner": "scanner-primary", "fingerprint": "3173a49e9cb9a7b3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f7a2fa03f3c90977", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/generate-openapi.ts:33"}, "properties": {"repobilityId": "30f662088ea9a99b", "scanner": "scanner-primary", "fingerprint": "f7a2fa03f3c90977", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-800a10d8a1ed7932", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/sync-stripe-prices.js:25"}, "properties": {"repobilityId": "3530eb99c1697914", "scanner": "scanner-primary", "fingerprint": "800a10d8a1ed7932", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-963a5f21014519b6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/scripts/sync-stripe-prices.ts:62"}, "properties": {"repobilityId": "734be7232a505b64", "scanner": "scanner-primary", "fingerprint": "963a5f21014519b6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-10c2e549741ae56a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/seed.ts:29"}, "properties": {"repobilityId": "0f25998c0552983b", "scanner": "scanner-primary", "fingerprint": "10c2e549741ae56a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-93f44c5abc40a016", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 backend/src/main.ts:59"}, "properties": {"repobilityId": "b6b8837ef125dd71", "scanner": "scanner-primary", "fingerprint": "93f44c5abc40a016", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c3446b178b7d8286", "level": "warning", "message": {"text": "Dockerfile runs as root: admin/Dockerfile"}, "properties": {"repobilityId": "8e52b63aacab3ec7", "scanner": "scanner-primary", "fingerprint": "c3446b178b7d8286", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-6edc7d50d68a358c", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "3536b61589894d07", "scanner": "scanner-primary", "fingerprint": "6edc7d50d68a358c", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "admin/Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-097f08ff98e759d4", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "properties": {"repobilityId": "e7fc318c10024f19", "scanner": "scanner-primary", "fingerprint": "097f08ff98e759d4", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "admin/Dockerfile"}, "region": {"startLine": 30}}}]}, {"ruleId": "scanner-1f66ad88286ca30a", "level": "warning", "message": {"text": "Dockerfile runs as root: backend/Dockerfile"}, "properties": {"repobilityId": "7afd2b0e8a8c9eeb", "scanner": "scanner-primary", "fingerprint": "1f66ad88286ca30a", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-3d2a6283f9ebab24", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "e866ff9772e76d62", "scanner": "scanner-primary", "fingerprint": "3d2a6283f9ebab24", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3d2a6283f9ebab24", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "8becb6834d4e36ea", "scanner": "scanner-primary", "fingerprint": "3d2a6283f9ebab24", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/Dockerfile"}, "region": {"startLine": 9}}}]}, {"ruleId": "scanner-3ceed35c3ef0e2e4", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: golang:1.25-alpine"}, "properties": {"repobilityId": "7568e08608f12fff", "scanner": "scanner-primary", "fingerprint": "3ceed35c3ef0e2e4", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend-rewrite-go/Dockerfile"}, "region": {"startLine": 5}}}]}, {"ruleId": "scanner-9661a3f2c0b88853", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: gcr.io/distroless/static-debian12:nonroot"}, "properties": {"repobilityId": "601e8ad0287f0bf0", "scanner": "scanner-primary", "fingerprint": "9661a3f2c0b88853", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend-rewrite-go/Dockerfile"}, "region": {"startLine": 36}}}]}, {"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-acc4597922133411", "level": "error", "message": {"text": "Runtime dotenv file present in repo: admin/.env.production"}, "properties": {"repobilityId": "6d233d184c6e87a4", "scanner": "scanner-primary", "fingerprint": "acc4597922133411", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["secrets", "config", "env-file", "runtime-env"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "admin/.env.production"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-43247045256bd19d", "level": "error", "message": {"text": "Possible secret in scripts/test-linux-api-smoke.py"}, "properties": {"repobilityId": "8f498093cf2756f8", "scanner": "scanner-primary", "fingerprint": "43247045256bd19d", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/test-linux-api-smoke.py"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-b99a6494f302fb3e", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/components/Checkout.tsx:186"}, "properties": {"repobilityId": "f195e16ffac39385", "scanner": "scanner-primary", "fingerprint": "b99a6494f302fb3e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/components/Checkout.tsx"}, "region": {"startLine": 186}}}]}, {"ruleId": "scanner-02b40ce713a72816", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/components/LoginForm.tsx:30"}, "properties": {"repobilityId": "d01d4a01abd04b8d", "scanner": "scanner-primary", "fingerprint": "02b40ce713a72816", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/components/LoginForm.tsx"}, "region": {"startLine": 30}}}]}, {"ruleId": "scanner-a3a514b724cf6c72", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/components/SignupForm.tsx:35"}, "properties": {"repobilityId": "011d8509e4e88876", "scanner": "scanner-primary", "fingerprint": "a3a514b724cf6c72", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/components/SignupForm.tsx"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-72de1a0bb1f7ad21", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in website/src/lib/socialAuth.ts:87"}, "properties": {"repobilityId": "96f9c1f204612388", "scanner": "scanner-primary", "fingerprint": "72de1a0bb1f7ad21", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "website/src/lib/socialAuth.ts"}, "region": {"startLine": 87}}}]}, {"ruleId": "scanner-60895657d1281dc6", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in admin/src/auth.ts:22"}, "properties": {"repobilityId": "b15870b8d395aced", "scanner": "scanner-primary", "fingerprint": "60895657d1281dc6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "admin/src/auth.ts"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-63ace385acde3b59", "level": "error", "message": {"text": "Possible secret in admin/e2e/report-bug.spec.ts"}, "properties": {"repobilityId": "2926ba2213800a81", "scanner": "scanner-primary", "fingerprint": "63ace385acde3b59", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "admin/e2e/report-bug.spec.ts"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-ce670926e37f82b9", "level": "error", "message": {"text": "Possible secret in backend/test/integration/auth-login.int-spec.ts"}, "properties": {"repobilityId": "a176c56ceaa07c83", "scanner": "scanner-primary", "fingerprint": "ce670926e37f82b9", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/test/integration/auth-login.int-spec.ts"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-ce670926e37f82b9", "level": "error", "message": {"text": "Possible secret in backend/test/integration/auth-login.int-spec.ts"}, "properties": {"repobilityId": "a176c56ceaa07c83", "scanner": "scanner-primary", "fingerprint": "ce670926e37f82b9", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/test/integration/auth-login.int-spec.ts"}, "region": {"startLine": 76}}}]}, {"ruleId": "scanner-d5afed38e7e042e1", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e4ace8c1946588ca", "scanner": "scanner-primary", "fingerprint": "d5afed38e7e042e1", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightMobile/.github/workflows/play-deploy.yml"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-d5afed38e7e042e1", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "d7ebdb44f4638e92", "scanner": "scanner-primary", "fingerprint": "d5afed38e7e042e1", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightMobile/.github/workflows/play-deploy.yml"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-d5afed38e7e042e1", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "f864b39222698746", "scanner": "scanner-primary", "fingerprint": "d5afed38e7e042e1", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightMobile/.github/workflows/play-deploy.yml"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-d5afed38e7e042e1", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "c3a2176f6a327b0c", "scanner": "scanner-primary", "fingerprint": "d5afed38e7e042e1", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "DraftRightMobile/.github/workflows/play-deploy.yml"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "6925b7b3d09ba0c0", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 55}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "b89b83380e90bbc8", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 58}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8a578fb545f1ad27", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 113}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8a578fb545f1ad27", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 178}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "c57e050b1d45a4d1", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 186}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "6925b7b3d09ba0c0", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 213}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "a77fe851b00663a8", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 216}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "6925b7b3d09ba0c0", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 378}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "b89b83380e90bbc8", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 381}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "85520f0c1dc5c5d0", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 386}}}]}, {"ruleId": "scanner-360cb263256aacfa", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8a578fb545f1ad27", "scanner": "scanner-primary", "fingerprint": "360cb263256aacfa", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 451}}}]}, {"ruleId": "scanner-6e61fb60af308a45", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "25ed9c052ad5a584", "scanner": "scanner-primary", "fingerprint": "6e61fb60af308a45", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build-windows.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "8c87c5e96db3757d", "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": "79f0cdf851233039", "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": "f3d84d8d994755d3", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "6269ea7c23047319", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "31c12785014c461f", "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": "cf897a66a46f27f2", "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": "4a835b21ba943cf4", "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": "ed1af3f5e742c0ad", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-bea357a6497a2d5d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: CLAUDE.md"}, "properties": {"repobilityId": "aae72df3934829ac", "scanner": "scanner-primary", "fingerprint": "bea357a6497a2d5d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-9917d6c3e8dde0f1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/AccountPage.tsx:117"}, "properties": {"repobilityId": "4f10a06bbbaccbb2", "scanner": "scanner-primary", "fingerprint": "9917d6c3e8dde0f1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-dc686e3864022e0a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/SuggestFeatureWidget.tsx:53"}, "properties": {"repobilityId": "7f60d9d1cbb9f7c4", "scanner": "scanner-primary", "fingerprint": "dc686e3864022e0a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f302c83682007ad0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/FeedbackBoard.tsx:227"}, "properties": {"repobilityId": "558393d413e9f328", "scanner": "scanner-primary", "fingerprint": "f302c83682007ad0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f5095092b1d1ec3c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 website/src/components/Playground.tsx:83"}, "properties": {"repobilityId": "29598b5bc5904a03", "scanner": "scanner-primary", "fingerprint": "f5095092b1d1ec3c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b4ba902855cd33ad", "level": "none", "message": {"text": "Commented-code block (7 lines) in DraftRightLinux/draftright/application.py:61"}, "properties": {"repobilityId": "036074421a8dea91", "scanner": "scanner-primary", "fingerprint": "b4ba902855cd33ad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-aa0eee5a7c38eaed", "level": "note", "message": {"text": "Legacy-named symbol `_on_copy` in DraftRightLinux/draftright/ui/checkout_dialogs.py:184"}, "properties": {"repobilityId": "f701709b4f17a487", "scanner": "scanner-primary", "fingerprint": "aa0eee5a7c38eaed", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-e36fe614b4ebcec9", "level": "none", "message": {"text": "Commented-code block (5 lines) in DraftRightLinux/draftright/ui/settings_window.py:137"}, "properties": {"repobilityId": "0d22129b7f87bc67", "scanner": "scanner-primary", "fingerprint": "e36fe614b4ebcec9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-81002bf243ac9b14", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 DraftRightLinux/draftright/ui/settings_window.py:461"}, "properties": {"repobilityId": "3798ae231fc82876", "scanner": "scanner-primary", "fingerprint": "81002bf243ac9b14", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0eb8acd587f197bc", "level": "note", "message": {"text": "Legacy-named symbol `on_copy` in DraftRightLinux/draftright/ui/rewrite_panel.py:257"}, "properties": {"repobilityId": "50114753e90c6b2d", "scanner": "scanner-primary", "fingerprint": "0eb8acd587f197bc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-91f158e3718aee02", "level": "note", "message": {"text": "Legacy-named symbol `_simulate_copy` in DraftRightLinux/draftright/services/clipboard_service.py:69"}, "properties": {"repobilityId": "42f915df9f2c6cbe", "scanner": "scanner-primary", "fingerprint": "91f158e3718aee02", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-fcf160235c8ba92e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/api.ts:8"}, "properties": {"repobilityId": "cc81639ed4fcbbb1", "scanner": "scanner-primary", "fingerprint": "fcf160235c8ba92e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-126323862150897c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 admin/src/pages/BugReportsPage.tsx:90"}, "properties": {"repobilityId": "3fea81aab6588c37", "scanner": "scanner-primary", "fingerprint": "126323862150897c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-af83dd37434b42aa", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/scripts/sync-stripe-prices.ts:110"}, "properties": {"repobilityId": "c3433ade9b983d98", "scanner": "scanner-primary", "fingerprint": "af83dd37434b42aa", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6361fc820086e021", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/config/env.schema.ts:83"}, "properties": {"repobilityId": "8b52ea1345f2fc4b", "scanner": "scanner-primary", "fingerprint": "6361fc820086e021", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e02c8a47ed52a36b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/auth/auth.service.ts:368"}, "properties": {"repobilityId": "691d78f9b5d0a2ac", "scanner": "scanner-primary", "fingerprint": "e02c8a47ed52a36b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-346df93ca5513988", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/src/health/health.controller.ts:10"}, "properties": {"repobilityId": "dddca20abe057d29", "scanner": "scanner-primary", "fingerprint": "346df93ca5513988", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6439d04bd1f2f67d", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/common/all-exceptions.filter.ts:84"}, "properties": {"repobilityId": "3886a3f90a4178b3", "scanner": "scanner-primary", "fingerprint": "6439d04bd1f2f67d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6f08cd76ce2b4a8a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/lemonsqueezy/lemonsqueezy.service.ts:58"}, "properties": {"repobilityId": "da2cfc38f66c2cca", "scanner": "scanner-primary", "fingerprint": "6f08cd76ce2b4a8a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4d8b907aceec73fd", "level": "none", "message": {"text": "Commented-code block (9 lines) in backend/src/ime-packs/dto/language-module.dto.ts:1"}, "properties": {"repobilityId": "497ea84fd325f0aa", "scanner": "scanner-primary", "fingerprint": "4d8b907aceec73fd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-34ccae2c10ee4bad", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/ai-providers/strategies/openai.strategy.ts:48"}, "properties": {"repobilityId": "6a206e05240b65f1", "scanner": "scanner-primary", "fingerprint": "34ccae2c10ee4bad", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-56915c46631f2afc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/ai-providers/strategies/anthropic.strategy.ts:38"}, "properties": {"repobilityId": "ea1d6955b6c32184", "scanner": "scanner-primary", "fingerprint": "56915c46631f2afc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1a6c62c863188e63", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/errors/fix-proposal.cron.ts:44"}, "properties": {"repobilityId": "cd015f6f0240e2a2", "scanner": "scanner-primary", "fingerprint": "1a6c62c863188e63", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-718a5272b61cd85d", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/admin/entities/app-settings.entity.ts:129"}, "properties": {"repobilityId": "0c69fd67647852c4", "scanner": "scanner-primary", "fingerprint": "718a5272b61cd85d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bd12c4dd374940b7", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/bug-reports/bug-reports.controller.ts:15"}, "properties": {"repobilityId": "26b83c89fe219a07", "scanner": "scanner-primary", "fingerprint": "bd12c4dd374940b7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e0f9ac87a4d41e27", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/bug-reports/dto/create-bug-report.dto.ts:15"}, "properties": {"repobilityId": "1ab296eaaf56b7a4", "scanner": "scanner-primary", "fingerprint": "e0f9ac87a4d41e27", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3aba5a4315841660", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/payment/payment.service.ts:56"}, "properties": {"repobilityId": "a39759b551dd418b", "scanner": "scanner-primary", "fingerprint": "3aba5a4315841660", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-71660ec869f4929a", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/src/payment/payment.controller.ts:66"}, "properties": {"repobilityId": "176e6188a17776b5", "scanner": "scanner-primary", "fingerprint": "71660ec869f4929a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4d15c910041b4572", "level": "none", "message": {"text": "Commented-code block (9 lines) in backend/src/payment/strategies/vietqr.strategy.ts:46"}, "properties": {"repobilityId": "0ebb168419235e35", "scanner": "scanner-primary", "fingerprint": "4d15c910041b4572", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5195cb7d564785eb", "level": "none", "message": {"text": "Commented-code block (10 lines) in backend/src/payment/strategies/lemonsqueezy.strategy.ts:107"}, "properties": {"repobilityId": "e5e983f0a6370f9b", "scanner": "scanner-primary", "fingerprint": "5195cb7d564785eb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-473ec117e95613d5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 backend/src/payment/strategies/lemonsqueezy.strategy.ts:127"}, "properties": {"repobilityId": "f12c7465a9540836", "scanner": "scanner-primary", "fingerprint": "473ec117e95613d5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d3455c0658e85742", "level": "none", "message": {"text": "Commented-code block (7 lines) in backend/src/payment/strategies/stripe.strategy.ts:67"}, "properties": {"repobilityId": "52e4a052ade44809", "scanner": "scanner-primary", "fingerprint": "d3455c0658e85742", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a60963cd4adc0c90", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/src/payment/strategies/payment-strategy.interface.ts:63"}, "properties": {"repobilityId": "2c34b4af8b91a400", "scanner": "scanner-primary", "fingerprint": "a60963cd4adc0c90", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7c8b918e1fee9558", "level": "note", "message": {"text": "20 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "bd1f6d44917e8105", "scanner": "scanner-primary", "fingerprint": "7c8b918e1fee9558", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "4680c1e933de62fd", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "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": "ace83629e027ccbc", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "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": "9cfb67d51c96364f", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "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": "ceaea48975a2c3ee", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "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": "5152a8c4e608e481", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "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": "128fa3b4d2437eb2", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-49c98f7cedd9c977", "level": "note", "message": {"text": "Near-duplicate function bodies in 4 places"}, "properties": {"repobilityId": "5c2d9b6e70fb94cc", "scanner": "scanner-primary", "fingerprint": "49c98f7cedd9c977", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-49c98f7cedd9c977", "level": "note", "message": {"text": "Near-duplicate function bodies in 4 places"}, "properties": {"repobilityId": "f053b1103dfca900", "scanner": "scanner-primary", "fingerprint": "49c98f7cedd9c977", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "172da9a38d591571", "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": "5850778dbe116aa5", "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": "14e858dd67228e2a", "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": "8eea06e027beb52f", "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": "c064be6016407c0c", "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": "1c9a334beb1af6c2", "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": "e84ad7876d490a46", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-1aff11349402159e", "level": "warning", "message": {"text": "Frontend route `/users/:id` has no Link/navigate to it \u2014 admin/src/App.tsx"}, "properties": {"repobilityId": "dc3d5d493ef64643", "scanner": "scanner-primary", "fingerprint": "1aff11349402159e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e7e5ccdbbd6e308f", "level": "error", "message": {"text": "Dangling fetch: GET https://oauth2.googleapis.com/tokeninfo?id_token=${idToken} (backend/src/auth/auth.service.ts:368)"}, "properties": {"repobilityId": "653540336e7f8429", "scanner": "scanner-primary", "fingerprint": "e7e5ccdbbd6e308f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-fdfedccd0a77ced3", "level": "error", "message": {"text": "Dangling fetch: GET https://appleid.apple.com/auth/keys (backend/src/auth/auth.service.ts:464)"}, "properties": {"repobilityId": "6aea193ac98e77ac", "scanner": "scanner-primary", "fingerprint": "fdfedccd0a77ced3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8a2ffb301cffe6a4", "level": "error", "message": {"text": "Dangling fetch: GET https://graph.facebook.com/me?fields=id,name,email,picture.type(large)&access_token=${accessToken} (backend/src/auth/auth.service.ts:485)"}, "properties": {"repobilityId": "d0ebb5a58e4ee332", "scanner": "scanner-primary", "fingerprint": "8a2ffb301cffe6a4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1c4176e167f6b167", "level": "error", "message": {"text": "Dangling fetch: DELETE https://api.lemonsqueezy.com/v1/customers/${user.lemonsqueezy_customer_id} (backend/src/payment/strategies/lemonsqueezy.strategy.ts:161)"}, "properties": {"repobilityId": "4064670ecd1bfc12", "scanner": "scanner-primary", "fingerprint": "1c4176e167f6b167", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8292c0931391749a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/register"}, "properties": {"repobilityId": "d89f047d2e273d13", "scanner": "scanner-primary", "fingerprint": "8292c0931391749a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8fdbacfe9430a6ed", "level": "note", "message": {"text": "Unused endpoint: POST /auth/login"}, "properties": {"repobilityId": "743b1ea2f563f80c", "scanner": "scanner-primary", "fingerprint": "8fdbacfe9430a6ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b36892106ecdc9aa", "level": "note", "message": {"text": "Unused endpoint: POST /auth/refresh"}, "properties": {"repobilityId": "a0b243d33b738ce6", "scanner": "scanner-primary", "fingerprint": "b36892106ecdc9aa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ccadf58fea366726", "level": "note", "message": {"text": "Unused endpoint: POST /auth/verify-email"}, "properties": {"repobilityId": "3855028109a550c8", "scanner": "scanner-primary", "fingerprint": "ccadf58fea366726", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ff5660488b9ce2ca", "level": "note", "message": {"text": "Unused endpoint: POST /auth/resend-verification"}, "properties": {"repobilityId": "46ce6993fdf9d558", "scanner": "scanner-primary", "fingerprint": "ff5660488b9ce2ca", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e2fe5b92648ca462", "level": "note", "message": {"text": "Unused endpoint: POST /auth/forgot-password"}, "properties": {"repobilityId": "eef2a63e08ee5f47", "scanner": "scanner-primary", "fingerprint": "e2fe5b92648ca462", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-deb8df763a50c73a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/reset-password"}, "properties": {"repobilityId": "0020c196abb9803f", "scanner": "scanner-primary", "fingerprint": "deb8df763a50c73a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b977f7cf742075a3", "level": "note", "message": {"text": "Unused endpoint: POST /auth/social"}, "properties": {"repobilityId": "5fdbdc03c83f0381", "scanner": "scanner-primary", "fingerprint": "b977f7cf742075a3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4585c350da9e880d", "level": "note", "message": {"text": "Unused endpoint: POST /auth/change-password"}, "properties": {"repobilityId": "79eff1876b11442f", "scanner": "scanner-primary", "fingerprint": "4585c350da9e880d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ac42422b23e45104", "level": "note", "message": {"text": "Unused endpoint: GET /auth/me"}, "properties": {"repobilityId": "c154dc44924dda67", "scanner": "scanner-primary", "fingerprint": "ac42422b23e45104", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2346b4b4a8d305f0", "level": "note", "message": {"text": "Unused endpoint: DELETE /auth/account"}, "properties": {"repobilityId": "07bbb073607eed5a", "scanner": "scanner-primary", "fingerprint": "2346b4b4a8d305f0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0b32589fd24b5ed", "level": "note", "message": {"text": "Unused endpoint: GET /auth/account"}, "properties": {"repobilityId": "3f86c0709fbf1bf1", "scanner": "scanner-primary", "fingerprint": "b0b32589fd24b5ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7e85a54b2b112eb8", "level": "note", "message": {"text": "Unused endpoint: DELETE /auth/extension-tokens/:id"}, "properties": {"repobilityId": "9388f372c3816d7c", "scanner": "scanner-primary", "fingerprint": "7e85a54b2b112eb8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0aa2de383afa1ce", "level": "note", "message": {"text": "Unused endpoint: POST /lemonsqueezy/checkout"}, "properties": {"repobilityId": "577ce5695a22e3ce", "scanner": "scanner-primary", "fingerprint": "b0aa2de383afa1ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3197f6861ed09dd7", "level": "note", "message": {"text": "Unused endpoint: GET /lemonsqueezy/portal"}, "properties": {"repobilityId": "3318a9ae3c05cb95", "scanner": "scanner-primary", "fingerprint": "3197f6861ed09dd7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-56639343c9df2d5b", "level": "note", "message": {"text": "Unused endpoint: POST /lemonsqueezy/webhook"}, "properties": {"repobilityId": "56c769108f41ce51", "scanner": "scanner-primary", "fingerprint": "56639343c9df2d5b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a80f0b102431958c", "level": "note", "message": {"text": "Unused endpoint: GET /updates/latest"}, "properties": {"repobilityId": "6bfd7bdcca358a51", "scanner": "scanner-primary", "fingerprint": "a80f0b102431958c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8ab86be72ab70aae", "level": "note", "message": {"text": "Unused endpoint: GET /ime-packs/manifest"}, "properties": {"repobilityId": "1f42ce98217404ab", "scanner": "scanner-primary", "fingerprint": "8ab86be72ab70aae", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9d592078c7e35e6d", "level": "note", "message": {"text": "Unused endpoint: GET /admin/bug-reports"}, "properties": {"repobilityId": "0004e9f2fd0841a5", "scanner": "scanner-primary", "fingerprint": "9d592078c7e35e6d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2c46eaf6c1b323d2", "level": "note", "message": {"text": "Unused endpoint: GET /admin/bug-reports/:id"}, "properties": {"repobilityId": "9fd16d89302f9254", "scanner": "scanner-primary", "fingerprint": "2c46eaf6c1b323d2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5dd022fbb457a43d", "level": "note", "message": {"text": "Unused endpoint: GET /admin/bug-reports/:id/screenshot"}, "properties": {"repobilityId": "d2bd4be617e94d1b", "scanner": "scanner-primary", "fingerprint": "5dd022fbb457a43d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3c66c0ba020991fc", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/bug-reports/:id"}, "properties": {"repobilityId": "921bb37a9663a0c9", "scanner": "scanner-primary", "fingerprint": "3c66c0ba020991fc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6b503549bccf8b29", "level": "note", "message": {"text": "Unused endpoint: DELETE /admin/bug-reports/:id"}, "properties": {"repobilityId": "4077625fc9833bb6", "scanner": "scanner-primary", "fingerprint": "6b503549bccf8b29", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c1c08f1cc647f314", "level": "note", "message": {"text": "Unused endpoint: POST /admin/bug-reports/:id/fix-proposal"}, "properties": {"repobilityId": "0428f28dd956cf65", "scanner": "scanner-primary", "fingerprint": "c1c08f1cc647f314", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-05d1d28f4f1f49ed", "level": "note", "message": {"text": "Unused endpoint: GET /admin/inbox/counts"}, "properties": {"repobilityId": "396f92de19dc2cb1", "scanner": "scanner-primary", "fingerprint": "05d1d28f4f1f49ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0fbcff8d1eca53cc", "level": "note", "message": {"text": "Unused endpoint: GET /admin/inbox"}, "properties": {"repobilityId": "9caf6e6a491670b3", "scanner": "scanner-primary", "fingerprint": "0fbcff8d1eca53cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0400039c6249f60b", "level": "note", "message": {"text": "Unused endpoint: GET /admin/errors"}, "properties": {"repobilityId": "0d775211a2ccb70b", "scanner": "scanner-primary", "fingerprint": "0400039c6249f60b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cdfb9c96d94f098a", "level": "note", "message": {"text": "Unused endpoint: GET /admin/errors/:id"}, "properties": {"repobilityId": "4c3e328d3dfe8ac4", "scanner": "scanner-primary", "fingerprint": "cdfb9c96d94f098a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fddac3b91a26c420", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/errors/:id"}, "properties": {"repobilityId": "2617b3c22041b3ef", "scanner": "scanner-primary", "fingerprint": "fddac3b91a26c420", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e3ea8b261adbbbd", "level": "note", "message": {"text": "Unused endpoint: DELETE /admin/errors/:id"}, "properties": {"repobilityId": "24d813584d5dce0c", "scanner": "scanner-primary", "fingerprint": "8e3ea8b261adbbbd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-64f833f2bc745a75", "level": "note", "message": {"text": "Unused endpoint: POST /admin/errors/:id/suggest-fix"}, "properties": {"repobilityId": "ba63f22b48e45d61", "scanner": "scanner-primary", "fingerprint": "64f833f2bc745a75", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6b067d028514918e", "level": "note", "message": {"text": "Unused endpoint: POST /admin/errors/run-ai-cron"}, "properties": {"repobilityId": "160300af1e137602", "scanner": "scanner-primary", "fingerprint": "6b067d028514918e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-66acf2ed6319dc66", "level": "note", "message": {"text": "Unused endpoint: GET /admin/releases"}, "properties": {"repobilityId": "5cb91e05b898406b", "scanner": "scanner-primary", "fingerprint": "66acf2ed6319dc66", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-992661aa1ae3985c", "level": "note", "message": {"text": "Unused endpoint: POST /admin/releases"}, "properties": {"repobilityId": "a70ffa5b888669f4", "scanner": "scanner-primary", "fingerprint": "992661aa1ae3985c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ebb446f1a1695458", "level": "note", "message": {"text": "Unused endpoint: DELETE /admin/releases/:platform/:channel"}, "properties": {"repobilityId": "a294f64dd1dfdfe8", "scanner": "scanner-primary", "fingerprint": "ebb446f1a1695458", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1fa15bd78bce54cf", "level": "note", "message": {"text": "Unused endpoint: POST /admin/release-policies"}, "properties": {"repobilityId": "60c50269a8118596", "scanner": "scanner-primary", "fingerprint": "1fa15bd78bce54cf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-233109e646627809", "level": "note", "message": {"text": "Unused endpoint: GET /admin/email-logs"}, "properties": {"repobilityId": "892332a1750f78bc", "scanner": "scanner-primary", "fingerprint": "233109e646627809", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7127a9563bb17fbc", "level": "note", "message": {"text": "Unused endpoint: GET /admin/email-templates"}, "properties": {"repobilityId": "8fd9a02886ed9f23", "scanner": "scanner-primary", "fingerprint": "7127a9563bb17fbc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b309bf002a5dc943", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/email-templates/:key"}, "properties": {"repobilityId": "ffb77cdd72fee948", "scanner": "scanner-primary", "fingerprint": "b309bf002a5dc943", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-433d547eccb1ae7e", "level": "note", "message": {"text": "Unused endpoint: DELETE /admin/email-templates/:key"}, "properties": {"repobilityId": "8d58b056f027ab48", "scanner": "scanner-primary", "fingerprint": "433d547eccb1ae7e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1a41cb602c21e715", "level": "note", "message": {"text": "Unused endpoint: GET /admin/email-templates/:key/preview"}, "properties": {"repobilityId": "a8f3a579aff5e869", "scanner": "scanner-primary", "fingerprint": "1a41cb602c21e715", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e2ad6d44231b81ad", "level": "note", "message": {"text": "Unused endpoint: GET /admin/settings"}, "properties": {"repobilityId": "3eab90f16c88d2a4", "scanner": "scanner-primary", "fingerprint": "e2ad6d44231b81ad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-967a1069385a4354", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/settings"}, "properties": {"repobilityId": "e10006e6941f5936", "scanner": "scanner-primary", "fingerprint": "967a1069385a4354", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9ac44a67d38fe1f1", "level": "note", "message": {"text": "Unused endpoint: POST /admin/settings/test-email"}, "properties": {"repobilityId": "21eb74a4ad3c5610", "scanner": "scanner-primary", "fingerprint": "9ac44a67d38fe1f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dd159bd05997c05c", "level": "note", "message": {"text": "Unused endpoint: GET /admin/stats"}, "properties": {"repobilityId": "685261c521ba7924", "scanner": "scanner-primary", "fingerprint": "dd159bd05997c05c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0aba7f1883cb96f2", "level": "note", "message": {"text": "Unused endpoint: GET /admin/users"}, "properties": {"repobilityId": "fb793a2d8a8468de", "scanner": "scanner-primary", "fingerprint": "0aba7f1883cb96f2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3bb3ff08475b5e3e", "level": "note", "message": {"text": "Unused endpoint: GET /admin/users/:id"}, "properties": {"repobilityId": "895106659586c17a", "scanner": "scanner-primary", "fingerprint": "3bb3ff08475b5e3e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f24cea56cd2023a1", "level": "note", "message": {"text": "Unused endpoint: PATCH /admin/users/:id"}, "properties": {"repobilityId": "71c54e53efbfb82f", "scanner": "scanner-primary", "fingerprint": "f24cea56cd2023a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2273ac666d251484", "level": "note", "message": {"text": "Unused endpoint: GET /admin/plans"}, "properties": {"repobilityId": "4ed25adf580dd952", "scanner": "scanner-primary", "fingerprint": "2273ac666d251484", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-922eccd4e86b578d", "level": "note", "message": {"text": "Unused endpoint: POST /admin/plans"}, "properties": {"repobilityId": "790b0e5aeef15f47", "scanner": "scanner-primary", "fingerprint": "922eccd4e86b578d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}