{"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-8e5e58b6115aa102", "name": "Possibly dead Python function: cached_entry_count", "shortDescription": {"text": "Possibly dead Python function: cached_entry_count"}, "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-e32a96edb943f6b1", "name": "Possibly dead Python function: reset_caches", "shortDescription": {"text": "Possibly dead Python function: reset_caches"}, "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-f452a4d12be152ea", "name": "Possibly dead Python function: clear_cache", "shortDescription": {"text": "Possibly dead Python function: clear_cache"}, "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-e31677fc44f877ca", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/people/page.tsx:658", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/people/page.tsx:658"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6ba8ca3b6440c588", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/search/page.tsx:430", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/search/page.tsx:430"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b8f2e097ed7430cb", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/households/page.tsx:354", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/households/page.tsx:354"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-45209f75d4b3738d", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/address/page.tsx:517", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/address/page.tsx:517"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d01167ce4494f8f4", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/components/CallsignCard.tsx:74", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/components/CallsignCard.tsx:74"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-df915defd2d38a6e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/SearchBar.tsx:503", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/SearchBar.tsx:503"}, "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-4ddb9ef380231057", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/lib/format.ts:123", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/lib/format.ts:123"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-eea7d81d529f0254", "name": "Stray `console.log` in TS/JS \u2014 frontend/lib/__tests__/ocrCleanNameDict.test.ts:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/lib/__tests__/ocrCleanNameDict.test.ts:24"}, "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-714c31ca9f474ae6", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-faa134129e5545ff", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4e83fa32b6a913c6", "name": "Dockerfile runs as root: caddy/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: caddy/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-e6f3a8b88a1d5a77", "name": "Docker base image is tag-pinned but not digest-pinned: caddy:2-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: caddy:2-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-66750e68cd64b6f2", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/app/people/page.tsx:658", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/people/page.tsx:658"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d17bc7cd8668a421", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/app/households/page.tsx:354", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/households/page.tsx:354"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-039c1dcaba0df94d", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/app/address/page.tsx:517", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/address/page.tsx:517"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6ba9bfab5f283202", "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-b769174c9fcf8ea8", "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-4c8ed1f015387c8a", "name": "Very large file: frontend/app/search/page.tsx (1902 lines)", "shortDescription": {"text": "Very large file: frontend/app/search/page.tsx (1902 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7ea3984538539207", "name": "Very large file: frontend/app/callsign/[cs]/page.tsx (3060 lines)", "shortDescription": {"text": "Very large file: frontend/app/callsign/[cs]/page.tsx (3060 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "2 test file(s) for 148 source file(s) (ratio 0.01). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 64 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 30 placeholder/mock markers across 13 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c8acc63e4f66b3d9", "name": "Commented-code block (6 lines) in backend/app/main.py:240", "shortDescription": {"text": "Commented-code block (6 lines) in backend/app/main.py:240"}, "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-7aaeae258ff1c724", "name": "Commented-code block (11 lines) in backend/app/db.py:95", "shortDescription": {"text": "Commented-code block (11 lines) in backend/app/db.py:95"}, "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-5032a0025b778f6e", "name": "Commented-code block (5 lines) in backend/app/scripts/build_address_index.py:217", "shortDescription": {"text": "Commented-code block (5 lines) in backend/app/scripts/build_address_index.py:217"}, "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-8ad429b48c71bee3", "name": "Legacy-named symbol `model_copy` in backend/app/integrations/psk_reporter.py:530", "shortDescription": {"text": "Legacy-named symbol `model_copy` in backend/app/integrations/psk_reporter.py:530"}, "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-21a0e34746306c2d", "name": "Commented-code block (5 lines) in backend/app/integrations/psk_reporter.py:75", "shortDescription": {"text": "Commented-code block (5 lines) in backend/app/integrations/psk_reporter.py:75"}, "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-8ac728eed418698a", "name": "Legacy-named symbol `ocr_v2` in backend/app/integrations/provenance.py:5", "shortDescription": {"text": "Legacy-named symbol `ocr_v2` in backend/app/integrations/provenance.py:5"}, "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-d7a19c3b13aa50d2", "name": "Commented-code block (5 lines) in backend/app/integrations/provenance.py:86", "shortDescription": {"text": "Commented-code block (5 lines) in backend/app/integrations/provenance.py:86"}, "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-1828ccbe93806271", "name": "Legacy-named symbol `model_copy` in backend/app/integrations/qrz_public.py:585", "shortDescription": {"text": "Legacy-named symbol `model_copy` in backend/app/integrations/qrz_public.py:585"}, "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-cfc26c16c9119c35", "name": "Commented-code block (5 lines) in backend/app/integrations/qrz_public.py:203", "shortDescription": {"text": "Commented-code block (5 lines) in backend/app/integrations/qrz_public.py:203"}, "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-dea00dbb6189e4ef", "name": "Commented-code block (6 lines) in backend/app/integrations/rbn.py:78", "shortDescription": {"text": "Commented-code block (6 lines) in backend/app/integrations/rbn.py:78"}, "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-6d573323e1bcfd97", "name": "Commented-code block (5 lines) in backend/app/routes/club.py:115", "shortDescription": {"text": "Commented-code block (5 lines) in backend/app/routes/club.py:115"}, "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-fb5635094c2bc1d9", "name": "Commented-code block (5 lines) in backend/app/routes/year.py:253", "shortDescription": {"text": "Commented-code block (5 lines) in backend/app/routes/year.py:253"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d0f33eaa8b8244eb", "name": "Commented-code block (6 lines) in backend/app/routes/browse.py:94", "shortDescription": {"text": "Commented-code block (6 lines) in backend/app/routes/browse.py:94"}, "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-29fda30306e8b41c", "name": "Legacy-named symbol `ocr_v2` in backend/app/routes/provenance.py:10", "shortDescription": {"text": "Legacy-named symbol `ocr_v2` in backend/app/routes/provenance.py:10"}, "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-ea4162a359ed2e9c", "name": "Commented-code block (10 lines) in backend/scripts/export_corrections.py:133", "shortDescription": {"text": "Commented-code block (10 lines) in backend/scripts/export_corrections.py:133"}, "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-76217703148ac094", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/next.config.mjs:12", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/next.config.mjs:12"}, "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-a5d88ca74ff4a6bc", "name": "Commented-code block (5 lines) in frontend/app/page.tsx:158", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/page.tsx:158"}, "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-96e1da956c73c1f6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/about/page.tsx:62", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/about/page.tsx:62"}, "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-e728c88795d5bd32", "name": "Commented-code block (7 lines) in frontend/app/year/[y]/page.tsx:326", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/app/year/[y]/page.tsx:326"}, "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-665d7ebd02b2246d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/year/[y]/page.tsx:103", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/year/[y]/page.tsx:103"}, "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-48c4ec4014093cbe", "name": "Commented-code block (5 lines) in frontend/app/search/page.tsx:201", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/search/page.tsx:201"}, "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-0ce43e268ed3e137", "name": "Commented-code block (7 lines) in frontend/app/state/[s]/page.tsx:233", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/app/state/[s]/page.tsx:233"}, "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-611b818c98ac1bce", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/state/[s]/page.tsx:111", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/state/[s]/page.tsx:111"}, "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-8af255a839edcd08", "name": "Commented-code block (7 lines) in frontend/app/callsign/[cs]/page.tsx:62", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/app/callsign/[cs]/page.tsx:62"}, "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-69fe27441d45d6c6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/cohorts/page.tsx:422", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/cohorts/page.tsx:422"}, "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-3a2b024a379c545f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/club/[slug]/page.tsx:97", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/club/[slug]/page.tsx:97"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a6a7e9d62a54b8e5", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/SourceViewer.tsx:65", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/SourceViewer.tsx:65"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-db6ca872e2462a58", "name": "Commented-code block (6 lines) in frontend/components/SearchBar.tsx:137", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/components/SearchBar.tsx: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-5b8929668c6c916b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/CiteThisRecord.tsx:172", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/CiteThisRecord.tsx:172"}, "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-2564046b5ef9f0f8", "name": "Commented-code block (6 lines) in frontend/lib/ocrClean.ts:80", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/lib/ocrClean.ts:80"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d91839e514b278e3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/club_api.ts:62", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/club_api.ts:62"}, "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-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:\nbackend/app/scripts/build_leaderboards.py:open_db, backend/app/scripts/build_cohorts.py:open_db\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-f341860ab6a90be6", "name": "Near-duplicate function bodies in 17 places", "shortDescription": {"text": "Near-duplicate function bodies in 17 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/integrations/phonetic_index.py:ensure_loaded, backend/app/integrations/phonetic_index.py:ensure_loaded, backend/app/integrations/leaderboards.py:ensure_loaded, backend/app/integrations/leaderboards.py:ensure_loaded\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:\nbackend/app/integrations/fcc_uls.py:stats, backend/app/integrations/fcc_uls.py:stats, backend/app/integrations/uls_history.py:stats, backend/app/integrations/uls_history.py:stats\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/integrations/address_index.py:reload, backend/app/integrations/address_index.py:reload, backend/app/integrations/address_index.py:reload\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-ccfd2109690d6012", "name": "FastAPI POST `resolve_adif` without auth dependency \u2014 backend/app/routes/adif.py:255", "shortDescription": {"text": "FastAPI POST `resolve_adif` without auth dependency \u2014 backend/app/routes/adif.py:255"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0182d9f69fc9394f", "name": "FastAPI POST `submit_correction` without auth dependency \u2014 backend/app/routes/corrections.py:204", "shortDescription": {"text": "FastAPI POST `submit_correction` without auth dependency \u2014 backend/app/routes/corrections.py:204"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8dd06358957a41f8", "name": "FastAPI PATCH `update_status` without auth dependency \u2014 backend/app/routes/corrections.py:283", "shortDescription": {"text": "FastAPI PATCH `update_status` without auth dependency \u2014 backend/app/routes/corrections.py:283"}, "fullDescription": {"text": "`@router.patch` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-c22d1ba132337999", "name": "FastAPI POST `scan_gedcom` without auth dependency \u2014 backend/app/routes/gedcom.py:352", "shortDescription": {"text": "FastAPI POST `scan_gedcom` without auth dependency \u2014 backend/app/routes/gedcom.py:352"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-efb112eccd42c9b1", "name": "Dangling fetch: GET /api/... (frontend/next.config.mjs:12)", "shortDescription": {"text": "Dangling fetch: GET /api/... (frontend/next.config.mjs:12)"}, "fullDescription": {"text": "`frontend/next.config.mjs:12` calls `GET /api/...` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/...`\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-89348ece6074ee06", "name": "Dangling fetch: POST /api/gedcom/scan (frontend/app/gedcom/page.tsx:69)", "shortDescription": {"text": "Dangling fetch: POST /api/gedcom/scan (frontend/app/gedcom/page.tsx:69)"}, "fullDescription": {"text": "`frontend/app/gedcom/page.tsx:69` calls `POST /api/gedcom/scan` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/gedcom/scan`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-0fa2d5a0e898f6c3", "name": "Dangling fetch: GET /api/stats/integrity (frontend/app/stats/IntegrityGauges.tsx:66)", "shortDescription": {"text": "Dangling fetch: GET /api/stats/integrity (frontend/app/stats/IntegrityGauges.tsx:66)"}, "fullDescription": {"text": "`frontend/app/stats/IntegrityGauges.tsx:66` calls `GET /api/stats/integrity` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/stats/integrity`\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-33ab1a58cb6dd744", "name": "Dangling fetch: GET /api/clubs/search?q=${encodeURIComponent(q)}&limit=3 (frontend/components/SearchBar.tsx:157)", "shortDescription": {"text": "Dangling fetch: GET /api/clubs/search?q=${encodeURIComponent(q)}&limit=3 (frontend/components/SearchBar.tsx:157)"}, "fullDescription": {"text": "`frontend/components/SearchBar.tsx:157` calls `GET /api/clubs/search?q=${encodeURIComponent(q)}&limit=3` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/clubs/search`\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-3952120f4bdbf326", "name": "Dangling fetch: GET /api/health (frontend/components/CiteThisRecord.tsx:172)", "shortDescription": {"text": "Dangling fetch: GET /api/health (frontend/components/CiteThisRecord.tsx:172)"}, "fullDescription": {"text": "`frontend/components/CiteThisRecord.tsx:172` calls `GET /api/health` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/health`\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-2417f01211abd85f", "name": "Dangling fetch: GET /api/qsl/date?${params.toString()} (frontend/components/QslWizard.tsx:212)", "shortDescription": {"text": "Dangling fetch: GET /api/qsl/date?${params.toString()} (frontend/components/QslWizard.tsx:212)"}, "fullDescription": {"text": "`frontend/components/QslWizard.tsx:212` calls `GET /api/qsl/date?${params.toString()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/qsl/date`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`backend/app/main.py` declares `GET /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-56608a3bd032f5f4", "name": "Unused endpoint: GET /{slug}", "shortDescription": {"text": "Unused endpoint: GET /{slug}"}, "fullDescription": {"text": "`backend/app/routes/club.py` declares `GET /{slug}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-52d19c6f09cb7886", "name": "Unused endpoint: GET /{slug}/history", "shortDescription": {"text": "Unused endpoint: GET /{slug}/history"}, "fullDescription": {"text": "`backend/app/routes/club.py` declares `GET /{slug}/history` 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-e32b7494994d1653", "name": "Unused endpoint: GET /{slug}/callsigns", "shortDescription": {"text": "Unused endpoint: GET /{slug}/callsigns"}, "fullDescription": {"text": "`backend/app/routes/club.py` declares `GET /{slug}/callsigns` 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-25e3ca9bdb691374", "name": "Unused endpoint: GET /{slug}/related", "shortDescription": {"text": "Unused endpoint: GET /{slug}/related"}, "fullDescription": {"text": "`backend/app/routes/club.py` declares `GET /{slug}/related` 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-ea0a2936e0aa50e6", "name": "Unused endpoint: GET /{cs}/uls", "shortDescription": {"text": "Unused endpoint: GET /{cs}/uls"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /{cs}/uls` 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-68ab4cd58fd393c3", "name": "Unused endpoint: GET /uls/_stats", "shortDescription": {"text": "Unused endpoint: GET /uls/_stats"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /uls/_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-5e44db252d6e10c7", "name": "Unused endpoint: GET /{cs}/rbn", "shortDescription": {"text": "Unused endpoint: GET /{cs}/rbn"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /{cs}/rbn` 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-5f2dc8064658adc7", "name": "Unused endpoint: GET /rbn/_stats", "shortDescription": {"text": "Unused endpoint: GET /rbn/_stats"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /rbn/_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-3784c23650c338e0", "name": "Unused endpoint: GET /{cs}/qrz", "shortDescription": {"text": "Unused endpoint: GET /{cs}/qrz"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /{cs}/qrz` 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-859573f822c944db", "name": "Unused endpoint: GET /qrz/_stats", "shortDescription": {"text": "Unused endpoint: GET /qrz/_stats"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /qrz/_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-f2e8830fc2d4b116", "name": "Unused endpoint: GET /{cs}/psk", "shortDescription": {"text": "Unused endpoint: GET /{cs}/psk"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /{cs}/psk` 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-32b91b4d930f71f5", "name": "Unused endpoint: GET /psk/_stats", "shortDescription": {"text": "Unused endpoint: GET /psk/_stats"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /psk/_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-094860a5cb9200d8", "name": "Unused endpoint: GET /{cs}", "shortDescription": {"text": "Unused endpoint: GET /{cs}"}, "fullDescription": {"text": "`backend/app/routes/activity.py` declares `GET /{cs}` 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-9260174de75b32ba", "name": "Unused endpoint: GET /categories", "shortDescription": {"text": "Unused endpoint: GET /categories"}, "fullDescription": {"text": "`backend/app/routes/records.py` declares `GET /categories` 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-833edacd3634c902", "name": "Unused endpoint: GET /meta", "shortDescription": {"text": "Unused endpoint: GET /meta"}, "fullDescription": {"text": "`backend/app/routes/records.py` declares `GET /meta` 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-9e82c1b91a9a4540", "name": "Unused endpoint: GET /{category}", "shortDescription": {"text": "Unused endpoint: GET /{category}"}, "fullDescription": {"text": "`backend/app/routes/records.py` declares `GET /{category}` 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-aac03d36169520da", "name": "Unused endpoint: GET /{category}/{rank}", "shortDescription": {"text": "Unused endpoint: GET /{category}/{rank}"}, "fullDescription": {"text": "`backend/app/routes/records.py` declares `GET /{category}/{rank}` 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-4cb73614b4fb642e", "name": "Unused endpoint: GET /db", "shortDescription": {"text": "Unused endpoint: GET /db"}, "fullDescription": {"text": "`backend/app/routes/health.py` declares `GET /db` 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-c4d996ff28991f77", "name": "Unused endpoint: GET /api/story/{cs}", "shortDescription": {"text": "Unused endpoint: GET /api/story/{cs}"}, "fullDescription": {"text": "`backend/app/routes/heritage.py` declares `GET /api/story/{cs}` 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-83e27fa9555ab572", "name": "Unused endpoint: GET /badge/{cs}.svg", "shortDescription": {"text": "Unused endpoint: GET /badge/{cs}.svg"}, "fullDescription": {"text": "`backend/app/routes/heritage.py` declares `GET /badge/{cs}.svg` 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-76f436c2a8093bc4", "name": "Unused endpoint: GET /card/{cs}.png", "shortDescription": {"text": "Unused endpoint: GET /card/{cs}.png"}, "fullDescription": {"text": "`backend/app/routes/heritage.py` declares `GET /card/{cs}.png` 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-d16e4fa529c520e9", "name": "Unused endpoint: GET /search", "shortDescription": {"text": "Unused endpoint: GET /search"}, "fullDescription": {"text": "`backend/app/routes/clubs.py` declares `GET /search` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-30e2f6ad8c52d2fa", "name": "Unused endpoint: GET /by-letter/{letter}", "shortDescription": {"text": "Unused endpoint: GET /by-letter/{letter}"}, "fullDescription": {"text": "`backend/app/routes/clubs.py` declares `GET /by-letter/{letter}` 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-12d6cc5378d0c6eb", "name": "Unused endpoint: GET /notable", "shortDescription": {"text": "Unused endpoint: GET /notable"}, "fullDescription": {"text": "`backend/app/routes/clubs.py` declares `GET /notable` 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-9630d39f953a327c", "name": "Unused endpoint: GET /types", "shortDescription": {"text": "Unused endpoint: GET /types"}, "fullDescription": {"text": "`backend/app/routes/clubs.py` declares `GET /types` 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-42ec90981d609e36", "name": "Unused endpoint: GET /{cs}/club", "shortDescription": {"text": "Unused endpoint: GET /{cs}/club"}, "fullDescription": {"text": "`backend/app/routes/callsign_club.py` declares `GET /{cs}/club` 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-c7192f216ffc9082", "name": "Unused endpoint: GET /growth", "shortDescription": {"text": "Unused endpoint: GET /growth"}, "fullDescription": {"text": "`backend/app/routes/stats.py` declares `GET /growth` 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-8445b057f72d6ece", "name": "Unused endpoint: GET /heatmap", "shortDescription": {"text": "Unused endpoint: GET /heatmap"}, "fullDescription": {"text": "`backend/app/routes/stats.py` declares `GET /heatmap` 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-9e7587958cb94164", "name": "Unused endpoint: GET /integrity", "shortDescription": {"text": "Unused endpoint: GET /integrity"}, "fullDescription": {"text": "`backend/app/routes/stats.py` declares `GET /integrity` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-da1ceb11dff2fb14", "name": "Unused endpoint: GET /cluster/{cluster_key:path}", "shortDescription": {"text": "Unused endpoint: GET /cluster/{cluster_key:path}"}, "fullDescription": {"text": "`backend/app/routes/address.py` declares `GET /cluster/{cluster_key:path}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-db4108924cc15d45", "name": "Unused endpoint: GET /callsign/{cs}", "shortDescription": {"text": "Unused endpoint: GET /callsign/{cs}"}, "fullDescription": {"text": "`backend/app/routes/address.py` declares `GET /callsign/{cs}` 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-0f03b7f686471890", "name": "Unused endpoint: GET /{cluster_key:path}/{surname}", "shortDescription": {"text": "Unused endpoint: GET /{cluster_key:path}/{surname}"}, "fullDescription": {"text": "`backend/app/routes/address.py` declares `GET /{cluster_key:path}/{surname}` 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-accbbfa265cd1438", "name": "Unused endpoint: GET /years", "shortDescription": {"text": "Unused endpoint: GET /years"}, "fullDescription": {"text": "`backend/app/routes/year.py` declares `GET /years` 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-bb49b72fcf1ed0c6", "name": "Unused endpoint: GET /year/{year}/summary", "shortDescription": {"text": "Unused endpoint: GET /year/{year}/summary"}, "fullDescription": {"text": "`backend/app/routes/year.py` declares `GET /year/{year}/summary` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f7f5705828b743a8", "name": "Unused endpoint: GET /year/{year}/entries", "shortDescription": {"text": "Unused endpoint: GET /year/{year}/entries"}, "fullDescription": {"text": "`backend/app/routes/year.py` declares `GET /year/{year}/entries` 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-dfa1b57ebf524401", "name": "Unused endpoint: POST /resolve", "shortDescription": {"text": "Unused endpoint: POST /resolve"}, "fullDescription": {"text": "`backend/app/routes/adif.py` declares `POST /resolve` 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-74ad4fab8b99d16e", "name": "Unused endpoint: GET /pairs", "shortDescription": {"text": "Unused endpoint: GET /pairs"}, "fullDescription": {"text": "`backend/app/routes/diff.py` declares `GET /pairs` 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-bf8708f93c5621bc", "name": "Unused endpoint: GET /timeline", "shortDescription": {"text": "Unused endpoint: GET /timeline"}, "fullDescription": {"text": "`backend/app/routes/diff.py` declares `GET /timeline` 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-1ca71992ed9fad66", "name": "Unused endpoint: GET /pair/{year_a}/{year_b}", "shortDescription": {"text": "Unused endpoint: GET /pair/{year_a}/{year_b}"}, "fullDescription": {"text": "`backend/app/routes/diff.py` declares `GET /pair/{year_a}/{year_b}` 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-aa4d84c9927bd3ec", "name": "Unused endpoint: GET /wwii", "shortDescription": {"text": "Unused endpoint: GET /wwii"}, "fullDescription": {"text": "`backend/app/routes/diff.py` declares `GET /wwii` 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-4ba3ea8eb248030a", "name": "Unused endpoint: GET /available", "shortDescription": {"text": "Unused endpoint: GET /available"}, "fullDescription": {"text": "`backend/app/routes/cohorts.py` declares `GET /available` 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-18a4887e7bea6b36", "name": "Unused endpoint: GET /compare", "shortDescription": {"text": "Unused endpoint: GET /compare"}, "fullDescription": {"text": "`backend/app/routes/cohorts.py` declares `GET /compare` 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-8f9421ca9c1482a4", "name": "Unused endpoint: GET /{key:path}", "shortDescription": {"text": "Unused endpoint: GET /{key:path}"}, "fullDescription": {"text": "`backend/app/routes/cohorts.py` declares `GET /{key:path}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-670c07fb91c2a5c3", "name": "Unused endpoint: GET /states", "shortDescription": {"text": "Unused endpoint: GET /states"}, "fullDescription": {"text": "`backend/app/routes/state.py` declares `GET /states` 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-cf366c191e669ea4", "name": "Unused endpoint: GET /state/{state}/summary", "shortDescription": {"text": "Unused endpoint: GET /state/{state}/summary"}, "fullDescription": {"text": "`backend/app/routes/state.py` declares `GET /state/{state}/summary` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-46c51608ce01a149", "name": "Unused endpoint: GET /state/{state}/entries", "shortDescription": {"text": "Unused endpoint: GET /state/{state}/entries"}, "fullDescription": {"text": "`backend/app/routes/state.py` declares `GET /state/{state}/entries` 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-9e73537db9bbcc43", "name": "Unused endpoint: GET /voyager/{name}", "shortDescription": {"text": "Unused endpoint: GET /voyager/{name}"}, "fullDescription": {"text": "`backend/app/routes/name_trends.py` declares `GET /voyager/{name}` 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-0ba4c47f2c44052b", "name": "Unused endpoint: GET /top-by-era", "shortDescription": {"text": "Unused endpoint: GET /top-by-era"}, "fullDescription": {"text": "`backend/app/routes/name_trends.py` declares `GET /top-by-era` 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-5272c40f73375d7a", "name": "Unused endpoint: GET /yl-index", "shortDescription": {"text": "Unused endpoint: GET /yl-index"}, "fullDescription": {"text": "`backend/app/routes/name_trends.py` declares `GET /yl-index` 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/24382"}, "properties": {"repository": "Atvriders/ham-callbook-site", "repoUrl": "https://github.com/Atvriders/ham-callbook-site", "branch": "main"}, "results": [{"ruleId": "scanner-8e5e58b6115aa102", "level": "note", "message": {"text": "Possibly dead Python function: cached_entry_count"}, "properties": {"repobilityId": "cac219258506219d", "scanner": "scanner-primary", "fingerprint": "8e5e58b6115aa102", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/db.py:176"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e32a96edb943f6b1", "level": "note", "message": {"text": "Possibly dead Python function: reset_caches"}, "properties": {"repobilityId": "6928392528d5788b", "scanner": "scanner-primary", "fingerprint": "e32a96edb943f6b1", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/db.py:183"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f452a4d12be152ea", "level": "note", "message": {"text": "Possibly dead Python function: clear_cache"}, "properties": {"repobilityId": "089acf3efecdf10a", "scanner": "scanner-primary", "fingerprint": "f452a4d12be152ea", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/integrations/psk_reporter.py:618"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e31677fc44f877ca", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/people/page.tsx:658"}, "properties": {"repobilityId": "6019f9140ff190d6", "scanner": "scanner-primary", "fingerprint": "e31677fc44f877ca", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-6ba8ca3b6440c588", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/search/page.tsx:430"}, "properties": {"repobilityId": "ab231b76ec534b07", "scanner": "scanner-primary", "fingerprint": "6ba8ca3b6440c588", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-b8f2e097ed7430cb", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/households/page.tsx:354"}, "properties": {"repobilityId": "103b720a27467df1", "scanner": "scanner-primary", "fingerprint": "b8f2e097ed7430cb", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-45209f75d4b3738d", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/address/page.tsx:517"}, "properties": {"repobilityId": "ce26926f64b7def4", "scanner": "scanner-primary", "fingerprint": "45209f75d4b3738d", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-d01167ce4494f8f4", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/components/CallsignCard.tsx:74"}, "properties": {"repobilityId": "057530b182679cb4", "scanner": "scanner-primary", "fingerprint": "d01167ce4494f8f4", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-df915defd2d38a6e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/SearchBar.tsx:503"}, "properties": {"repobilityId": "1be2b305313e5ac8", "scanner": "scanner-primary", "fingerprint": "df915defd2d38a6e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4ddb9ef380231057", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/lib/format.ts:123"}, "properties": {"repobilityId": "ab33880871f90711", "scanner": "scanner-primary", "fingerprint": "4ddb9ef380231057", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-eea7d81d529f0254", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/lib/__tests__/ocrCleanNameDict.test.ts:24"}, "properties": {"repobilityId": "45474981da782791", "scanner": "scanner-primary", "fingerprint": "eea7d81d529f0254", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-714c31ca9f474ae6", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "f614a1e41f331b37", "scanner": "scanner-primary", "fingerprint": "714c31ca9f474ae6", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "d73b5c6aa0380103", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "d1825bd2e0338f0e", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "197f373decad87d7", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-4e83fa32b6a913c6", "level": "warning", "message": {"text": "Dockerfile runs as root: caddy/Dockerfile"}, "properties": {"repobilityId": "609b61797b1e822d", "scanner": "scanner-primary", "fingerprint": "4e83fa32b6a913c6", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-e6f3a8b88a1d5a77", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: caddy:2-alpine"}, "properties": {"repobilityId": "c9992a252d2b5e82", "scanner": "scanner-primary", "fingerprint": "e6f3a8b88a1d5a77", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "caddy/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-66750e68cd64b6f2", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/people/page.tsx:658"}, "properties": {"repobilityId": "66b67a29e454e870", "scanner": "scanner-primary", "fingerprint": "66750e68cd64b6f2", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/app/people/page.tsx"}, "region": {"startLine": 658}}}]}, {"ruleId": "scanner-d17bc7cd8668a421", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/households/page.tsx:354"}, "properties": {"repobilityId": "5cbdffc8b3a1da7d", "scanner": "scanner-primary", "fingerprint": "d17bc7cd8668a421", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/app/households/page.tsx"}, "region": {"startLine": 354}}}]}, {"ruleId": "scanner-039c1dcaba0df94d", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/address/page.tsx:517"}, "properties": {"repobilityId": "21ab57c501f7e55d", "scanner": "scanner-primary", "fingerprint": "039c1dcaba0df94d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/app/address/page.tsx"}, "region": {"startLine": 517}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "1bf0fd1430c42e23", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "4ec74db6e1e49776", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 35}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "e0130f45ae8f6a41", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 38}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "21a8993f77ff9a4e", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 45}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "21a8993f77ff9a4e", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 54}}}]}, {"ruleId": "scanner-6ba9bfab5f283202", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "21a8993f77ff9a4e", "scanner": "scanner-primary", "fingerprint": "6ba9bfab5f283202", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 63}}}]}, {"ruleId": "scanner-b769174c9fcf8ea8", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "e34b6cb9b56931d2", "scanner": "scanner-primary", "fingerprint": "b769174c9fcf8ea8", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/build.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4c8ed1f015387c8a", "level": "note", "message": {"text": "Very large file: frontend/app/search/page.tsx (1902 lines)"}, "properties": {"repobilityId": "737b0a6e9a7bd163", "scanner": "scanner-primary", "fingerprint": "4c8ed1f015387c8a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-7ea3984538539207", "level": "note", "message": {"text": "Very large file: frontend/app/callsign/[cs]/page.tsx (3060 lines)"}, "properties": {"repobilityId": "2c9d371e239a493f", "scanner": "scanner-primary", "fingerprint": "7ea3984538539207", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "bc3c68fa7d7de8df", "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": "a600661dc45edfc4", "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": "04715746373af6ea", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "ccd8f2ebe7df9749", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-c8acc63e4f66b3d9", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/app/main.py:240"}, "properties": {"repobilityId": "ac797b00c83e2bdb", "scanner": "scanner-primary", "fingerprint": "c8acc63e4f66b3d9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7aaeae258ff1c724", "level": "none", "message": {"text": "Commented-code block (11 lines) in backend/app/db.py:95"}, "properties": {"repobilityId": "2b741bc8abf4c380", "scanner": "scanner-primary", "fingerprint": "7aaeae258ff1c724", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5032a0025b778f6e", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/app/scripts/build_address_index.py:217"}, "properties": {"repobilityId": "15999fdf12162b73", "scanner": "scanner-primary", "fingerprint": "5032a0025b778f6e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8ad429b48c71bee3", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in backend/app/integrations/psk_reporter.py:530"}, "properties": {"repobilityId": "a2794671203475a9", "scanner": "scanner-primary", "fingerprint": "8ad429b48c71bee3", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-21a0e34746306c2d", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/app/integrations/psk_reporter.py:75"}, "properties": {"repobilityId": "915afad2f9839092", "scanner": "scanner-primary", "fingerprint": "21a0e34746306c2d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8ac728eed418698a", "level": "note", "message": {"text": "Legacy-named symbol `ocr_v2` in backend/app/integrations/provenance.py:5"}, "properties": {"repobilityId": "ed5097df1c1a78f5", "scanner": "scanner-primary", "fingerprint": "8ac728eed418698a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-d7a19c3b13aa50d2", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/app/integrations/provenance.py:86"}, "properties": {"repobilityId": "0b18a59b9391d3b6", "scanner": "scanner-primary", "fingerprint": "d7a19c3b13aa50d2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1828ccbe93806271", "level": "note", "message": {"text": "Legacy-named symbol `model_copy` in backend/app/integrations/qrz_public.py:585"}, "properties": {"repobilityId": "9bc48dc5bc5e64a6", "scanner": "scanner-primary", "fingerprint": "1828ccbe93806271", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-cfc26c16c9119c35", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/app/integrations/qrz_public.py:203"}, "properties": {"repobilityId": "a1222820d4c19471", "scanner": "scanner-primary", "fingerprint": "cfc26c16c9119c35", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dea00dbb6189e4ef", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/app/integrations/rbn.py:78"}, "properties": {"repobilityId": "605a858a9a16dd36", "scanner": "scanner-primary", "fingerprint": "dea00dbb6189e4ef", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6d573323e1bcfd97", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/app/routes/club.py:115"}, "properties": {"repobilityId": "5b45661037428c6b", "scanner": "scanner-primary", "fingerprint": "6d573323e1bcfd97", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fb5635094c2bc1d9", "level": "none", "message": {"text": "Commented-code block (5 lines) in backend/app/routes/year.py:253"}, "properties": {"repobilityId": "98988c297111821d", "scanner": "scanner-primary", "fingerprint": "fb5635094c2bc1d9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d0f33eaa8b8244eb", "level": "none", "message": {"text": "Commented-code block (6 lines) in backend/app/routes/browse.py:94"}, "properties": {"repobilityId": "589efbcbbeed0023", "scanner": "scanner-primary", "fingerprint": "d0f33eaa8b8244eb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-29fda30306e8b41c", "level": "note", "message": {"text": "Legacy-named symbol `ocr_v2` in backend/app/routes/provenance.py:10"}, "properties": {"repobilityId": "60a568f12e93b26d", "scanner": "scanner-primary", "fingerprint": "29fda30306e8b41c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-ea4162a359ed2e9c", "level": "none", "message": {"text": "Commented-code block (10 lines) in backend/scripts/export_corrections.py:133"}, "properties": {"repobilityId": "8d8e382402536233", "scanner": "scanner-primary", "fingerprint": "ea4162a359ed2e9c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-76217703148ac094", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/next.config.mjs:12"}, "properties": {"repobilityId": "74b25bf1e507f75e", "scanner": "scanner-primary", "fingerprint": "76217703148ac094", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a5d88ca74ff4a6bc", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/page.tsx:158"}, "properties": {"repobilityId": "f24ddfb920a3bbe2", "scanner": "scanner-primary", "fingerprint": "a5d88ca74ff4a6bc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-96e1da956c73c1f6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/about/page.tsx:62"}, "properties": {"repobilityId": "00ad30daa383138e", "scanner": "scanner-primary", "fingerprint": "96e1da956c73c1f6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e728c88795d5bd32", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/app/year/[y]/page.tsx:326"}, "properties": {"repobilityId": "34cbdc30110405b4", "scanner": "scanner-primary", "fingerprint": "e728c88795d5bd32", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-665d7ebd02b2246d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/year/[y]/page.tsx:103"}, "properties": {"repobilityId": "50a5bb11a318711e", "scanner": "scanner-primary", "fingerprint": "665d7ebd02b2246d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-48c4ec4014093cbe", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/search/page.tsx:201"}, "properties": {"repobilityId": "91a22c9222672e3a", "scanner": "scanner-primary", "fingerprint": "48c4ec4014093cbe", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ce43e268ed3e137", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/app/state/[s]/page.tsx:233"}, "properties": {"repobilityId": "2e312c4801c2f727", "scanner": "scanner-primary", "fingerprint": "0ce43e268ed3e137", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-611b818c98ac1bce", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/state/[s]/page.tsx:111"}, "properties": {"repobilityId": "fb90c9c2391345c7", "scanner": "scanner-primary", "fingerprint": "611b818c98ac1bce", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8af255a839edcd08", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/app/callsign/[cs]/page.tsx:62"}, "properties": {"repobilityId": "e2d97ba62005b4ef", "scanner": "scanner-primary", "fingerprint": "8af255a839edcd08", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-69fe27441d45d6c6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/cohorts/page.tsx:422"}, "properties": {"repobilityId": "d3f3390f31b82ccc", "scanner": "scanner-primary", "fingerprint": "69fe27441d45d6c6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-3a2b024a379c545f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/club/[slug]/page.tsx:97"}, "properties": {"repobilityId": "1f86053530aa34b8", "scanner": "scanner-primary", "fingerprint": "3a2b024a379c545f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a6a7e9d62a54b8e5", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/SourceViewer.tsx:65"}, "properties": {"repobilityId": "9907b71f37cd87c4", "scanner": "scanner-primary", "fingerprint": "a6a7e9d62a54b8e5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-db6ca872e2462a58", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/components/SearchBar.tsx:137"}, "properties": {"repobilityId": "d456d347df21e6cb", "scanner": "scanner-primary", "fingerprint": "db6ca872e2462a58", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5b8929668c6c916b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/CiteThisRecord.tsx:172"}, "properties": {"repobilityId": "90a027598875eac4", "scanner": "scanner-primary", "fingerprint": "5b8929668c6c916b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2564046b5ef9f0f8", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/lib/ocrClean.ts:80"}, "properties": {"repobilityId": "cf59267ba857fdb1", "scanner": "scanner-primary", "fingerprint": "2564046b5ef9f0f8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d91839e514b278e3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/club_api.ts:62"}, "properties": {"repobilityId": "e7be5754a8aa52a2", "scanner": "scanner-primary", "fingerprint": "d91839e514b278e3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "62b061989f624192", "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": "8835e7b88371c958", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-f341860ab6a90be6", "level": "note", "message": {"text": "Near-duplicate function bodies in 17 places"}, "properties": {"repobilityId": "858f5b72bacb411b", "scanner": "scanner-primary", "fingerprint": "f341860ab6a90be6", "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": "2a6733d73bd0d509", "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": "cff14066e2003583", "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": "2395f5798fd61044", "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": "38f28d2f5c52aba4", "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": "780c55ae7b30c4e2", "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": "d71b950c3f139450", "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": "9db3c12380ce30e6", "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": "0cbc013d67186a76", "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": "c4d0ccaa17a15295", "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": "6a5378d0f155649a", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "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": "e108fc68b9d2e1ea", "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": "3c2a324fd7fecfa7", "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": "112cc2564c4d9765", "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": "81c590153607dab5", "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": "1332e20ab65f181c", "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": "023f588e19bfd1d0", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "27f32983cece8c67", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-ccfd2109690d6012", "level": "error", "message": {"text": "FastAPI POST `resolve_adif` without auth dependency \u2014 backend/app/routes/adif.py:255"}, "properties": {"repobilityId": "044829269a424420", "scanner": "scanner-primary", "fingerprint": "ccfd2109690d6012", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routes/adif.py"}, "region": {"startLine": 255}}}]}, {"ruleId": "scanner-0182d9f69fc9394f", "level": "error", "message": {"text": "FastAPI POST `submit_correction` without auth dependency \u2014 backend/app/routes/corrections.py:204"}, "properties": {"repobilityId": "cc7495765c31b898", "scanner": "scanner-primary", "fingerprint": "0182d9f69fc9394f", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routes/corrections.py"}, "region": {"startLine": 204}}}]}, {"ruleId": "scanner-8dd06358957a41f8", "level": "error", "message": {"text": "FastAPI PATCH `update_status` without auth dependency \u2014 backend/app/routes/corrections.py:283"}, "properties": {"repobilityId": "e685f6ee6bc5bc68", "scanner": "scanner-primary", "fingerprint": "8dd06358957a41f8", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routes/corrections.py"}, "region": {"startLine": 283}}}]}, {"ruleId": "scanner-c22d1ba132337999", "level": "error", "message": {"text": "FastAPI POST `scan_gedcom` without auth dependency \u2014 backend/app/routes/gedcom.py:352"}, "properties": {"repobilityId": "f9a2f0bf1b9a8bde", "scanner": "scanner-primary", "fingerprint": "c22d1ba132337999", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/routes/gedcom.py"}, "region": {"startLine": 352}}}]}, {"ruleId": "scanner-efb112eccd42c9b1", "level": "error", "message": {"text": "Dangling fetch: GET /api/... (frontend/next.config.mjs:12)"}, "properties": {"repobilityId": "91e9ae367dae5219", "scanner": "scanner-primary", "fingerprint": "efb112eccd42c9b1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-89348ece6074ee06", "level": "error", "message": {"text": "Dangling fetch: POST /api/gedcom/scan (frontend/app/gedcom/page.tsx:69)"}, "properties": {"repobilityId": "baf8c4250ee4a857", "scanner": "scanner-primary", "fingerprint": "89348ece6074ee06", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-0fa2d5a0e898f6c3", "level": "error", "message": {"text": "Dangling fetch: GET /api/stats/integrity (frontend/app/stats/IntegrityGauges.tsx:66)"}, "properties": {"repobilityId": "a1e9b9e72e46954e", "scanner": "scanner-primary", "fingerprint": "0fa2d5a0e898f6c3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-33ab1a58cb6dd744", "level": "error", "message": {"text": "Dangling fetch: GET /api/clubs/search?q=${encodeURIComponent(q)}&limit=3 (frontend/components/SearchBar.tsx:157)"}, "properties": {"repobilityId": "d9d2729ae0821172", "scanner": "scanner-primary", "fingerprint": "33ab1a58cb6dd744", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3952120f4bdbf326", "level": "error", "message": {"text": "Dangling fetch: GET /api/health (frontend/components/CiteThisRecord.tsx:172)"}, "properties": {"repobilityId": "264d6816a59a491c", "scanner": "scanner-primary", "fingerprint": "3952120f4bdbf326", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2417f01211abd85f", "level": "error", "message": {"text": "Dangling fetch: GET /api/qsl/date?${params.toString()} (frontend/components/QslWizard.tsx:212)"}, "properties": {"repobilityId": "edd6fe6e49af3c29", "scanner": "scanner-primary", "fingerprint": "2417f01211abd85f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "9a7ab29051c0367b", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-56608a3bd032f5f4", "level": "note", "message": {"text": "Unused endpoint: GET /{slug}"}, "properties": {"repobilityId": "b0310ac2ddf17371", "scanner": "scanner-primary", "fingerprint": "56608a3bd032f5f4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-52d19c6f09cb7886", "level": "note", "message": {"text": "Unused endpoint: GET /{slug}/history"}, "properties": {"repobilityId": "026077682cefdb0f", "scanner": "scanner-primary", "fingerprint": "52d19c6f09cb7886", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e32b7494994d1653", "level": "note", "message": {"text": "Unused endpoint: GET /{slug}/callsigns"}, "properties": {"repobilityId": "0a83a95313848e5a", "scanner": "scanner-primary", "fingerprint": "e32b7494994d1653", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-25e3ca9bdb691374", "level": "note", "message": {"text": "Unused endpoint: GET /{slug}/related"}, "properties": {"repobilityId": "a2456ffac6c3bb7b", "scanner": "scanner-primary", "fingerprint": "25e3ca9bdb691374", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ea0a2936e0aa50e6", "level": "note", "message": {"text": "Unused endpoint: GET /{cs}/uls"}, "properties": {"repobilityId": "626a2b4f36157390", "scanner": "scanner-primary", "fingerprint": "ea0a2936e0aa50e6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-68ab4cd58fd393c3", "level": "note", "message": {"text": "Unused endpoint: GET /uls/_stats"}, "properties": {"repobilityId": "46a16f6a5762dd51", "scanner": "scanner-primary", "fingerprint": "68ab4cd58fd393c3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5e44db252d6e10c7", "level": "note", "message": {"text": "Unused endpoint: GET /{cs}/rbn"}, "properties": {"repobilityId": "93a18126122a9c51", "scanner": "scanner-primary", "fingerprint": "5e44db252d6e10c7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5f2dc8064658adc7", "level": "note", "message": {"text": "Unused endpoint: GET /rbn/_stats"}, "properties": {"repobilityId": "83a6082ae60f4e8a", "scanner": "scanner-primary", "fingerprint": "5f2dc8064658adc7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3784c23650c338e0", "level": "note", "message": {"text": "Unused endpoint: GET /{cs}/qrz"}, "properties": {"repobilityId": "f69095ccdd7efa38", "scanner": "scanner-primary", "fingerprint": "3784c23650c338e0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-859573f822c944db", "level": "note", "message": {"text": "Unused endpoint: GET /qrz/_stats"}, "properties": {"repobilityId": "0a886d3d493d70aa", "scanner": "scanner-primary", "fingerprint": "859573f822c944db", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f2e8830fc2d4b116", "level": "note", "message": {"text": "Unused endpoint: GET /{cs}/psk"}, "properties": {"repobilityId": "eaee95df6866403c", "scanner": "scanner-primary", "fingerprint": "f2e8830fc2d4b116", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-32b91b4d930f71f5", "level": "note", "message": {"text": "Unused endpoint: GET /psk/_stats"}, "properties": {"repobilityId": "07ac80b00cd3b65d", "scanner": "scanner-primary", "fingerprint": "32b91b4d930f71f5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-094860a5cb9200d8", "level": "note", "message": {"text": "Unused endpoint: GET /{cs}"}, "properties": {"repobilityId": "54c39539ac5f47a8", "scanner": "scanner-primary", "fingerprint": "094860a5cb9200d8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9260174de75b32ba", "level": "note", "message": {"text": "Unused endpoint: GET /categories"}, "properties": {"repobilityId": "56f939718cce9406", "scanner": "scanner-primary", "fingerprint": "9260174de75b32ba", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-833edacd3634c902", "level": "note", "message": {"text": "Unused endpoint: GET /meta"}, "properties": {"repobilityId": "132ab20eeebce6f1", "scanner": "scanner-primary", "fingerprint": "833edacd3634c902", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e82c1b91a9a4540", "level": "note", "message": {"text": "Unused endpoint: GET /{category}"}, "properties": {"repobilityId": "9bfe384fbc6d40d3", "scanner": "scanner-primary", "fingerprint": "9e82c1b91a9a4540", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-aac03d36169520da", "level": "note", "message": {"text": "Unused endpoint: GET /{category}/{rank}"}, "properties": {"repobilityId": "d51237a3af9fd4cf", "scanner": "scanner-primary", "fingerprint": "aac03d36169520da", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4cb73614b4fb642e", "level": "note", "message": {"text": "Unused endpoint: GET /db"}, "properties": {"repobilityId": "bebc6ddc29edbcab", "scanner": "scanner-primary", "fingerprint": "4cb73614b4fb642e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c4d996ff28991f77", "level": "note", "message": {"text": "Unused endpoint: GET /api/story/{cs}"}, "properties": {"repobilityId": "f0fcf7cc697fb3b9", "scanner": "scanner-primary", "fingerprint": "c4d996ff28991f77", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-83e27fa9555ab572", "level": "note", "message": {"text": "Unused endpoint: GET /badge/{cs}.svg"}, "properties": {"repobilityId": "66b3b3ce52cf6a23", "scanner": "scanner-primary", "fingerprint": "83e27fa9555ab572", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76f436c2a8093bc4", "level": "note", "message": {"text": "Unused endpoint: GET /card/{cs}.png"}, "properties": {"repobilityId": "f8e5c41d35da9571", "scanner": "scanner-primary", "fingerprint": "76f436c2a8093bc4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d16e4fa529c520e9", "level": "note", "message": {"text": "Unused endpoint: GET /search"}, "properties": {"repobilityId": "1fa871dad1466ac6", "scanner": "scanner-primary", "fingerprint": "d16e4fa529c520e9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-30e2f6ad8c52d2fa", "level": "note", "message": {"text": "Unused endpoint: GET /by-letter/{letter}"}, "properties": {"repobilityId": "f47f358d4b12d5a0", "scanner": "scanner-primary", "fingerprint": "30e2f6ad8c52d2fa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-12d6cc5378d0c6eb", "level": "note", "message": {"text": "Unused endpoint: GET /notable"}, "properties": {"repobilityId": "d4065da47d8a24a4", "scanner": "scanner-primary", "fingerprint": "12d6cc5378d0c6eb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9630d39f953a327c", "level": "note", "message": {"text": "Unused endpoint: GET /types"}, "properties": {"repobilityId": "b0b029a807f22c39", "scanner": "scanner-primary", "fingerprint": "9630d39f953a327c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-42ec90981d609e36", "level": "note", "message": {"text": "Unused endpoint: GET /{cs}/club"}, "properties": {"repobilityId": "540adee898747ee4", "scanner": "scanner-primary", "fingerprint": "42ec90981d609e36", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c7192f216ffc9082", "level": "note", "message": {"text": "Unused endpoint: GET /growth"}, "properties": {"repobilityId": "f35de84735b570cf", "scanner": "scanner-primary", "fingerprint": "c7192f216ffc9082", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8445b057f72d6ece", "level": "note", "message": {"text": "Unused endpoint: GET /heatmap"}, "properties": {"repobilityId": "84a7884a5d65e30f", "scanner": "scanner-primary", "fingerprint": "8445b057f72d6ece", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e7587958cb94164", "level": "note", "message": {"text": "Unused endpoint: GET /integrity"}, "properties": {"repobilityId": "8ad9b20a039300f6", "scanner": "scanner-primary", "fingerprint": "9e7587958cb94164", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-da1ceb11dff2fb14", "level": "note", "message": {"text": "Unused endpoint: GET /cluster/{cluster_key:path}"}, "properties": {"repobilityId": "1138aa1366006bea", "scanner": "scanner-primary", "fingerprint": "da1ceb11dff2fb14", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-db4108924cc15d45", "level": "note", "message": {"text": "Unused endpoint: GET /callsign/{cs}"}, "properties": {"repobilityId": "76ac863fa0d0da5f", "scanner": "scanner-primary", "fingerprint": "db4108924cc15d45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0f03b7f686471890", "level": "note", "message": {"text": "Unused endpoint: GET /{cluster_key:path}/{surname}"}, "properties": {"repobilityId": "a886ad9a80312ee2", "scanner": "scanner-primary", "fingerprint": "0f03b7f686471890", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-accbbfa265cd1438", "level": "note", "message": {"text": "Unused endpoint: GET /years"}, "properties": {"repobilityId": "9098c3cc0cc572f4", "scanner": "scanner-primary", "fingerprint": "accbbfa265cd1438", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bb49b72fcf1ed0c6", "level": "note", "message": {"text": "Unused endpoint: GET /year/{year}/summary"}, "properties": {"repobilityId": "f7504b7270f70aca", "scanner": "scanner-primary", "fingerprint": "bb49b72fcf1ed0c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f7f5705828b743a8", "level": "note", "message": {"text": "Unused endpoint: GET /year/{year}/entries"}, "properties": {"repobilityId": "bb90eb4df4b7e9dc", "scanner": "scanner-primary", "fingerprint": "f7f5705828b743a8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dfa1b57ebf524401", "level": "note", "message": {"text": "Unused endpoint: POST /resolve"}, "properties": {"repobilityId": "241b24f3742bc5d8", "scanner": "scanner-primary", "fingerprint": "dfa1b57ebf524401", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-74ad4fab8b99d16e", "level": "note", "message": {"text": "Unused endpoint: GET /pairs"}, "properties": {"repobilityId": "e5dbb991c0d2929d", "scanner": "scanner-primary", "fingerprint": "74ad4fab8b99d16e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bf8708f93c5621bc", "level": "note", "message": {"text": "Unused endpoint: GET /timeline"}, "properties": {"repobilityId": "ff0645658b7479ae", "scanner": "scanner-primary", "fingerprint": "bf8708f93c5621bc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ca71992ed9fad66", "level": "note", "message": {"text": "Unused endpoint: GET /pair/{year_a}/{year_b}"}, "properties": {"repobilityId": "4bda0d70b99ed7b6", "scanner": "scanner-primary", "fingerprint": "1ca71992ed9fad66", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-aa4d84c9927bd3ec", "level": "note", "message": {"text": "Unused endpoint: GET /wwii"}, "properties": {"repobilityId": "ace085cad6b8f486", "scanner": "scanner-primary", "fingerprint": "aa4d84c9927bd3ec", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ba3ea8eb248030a", "level": "note", "message": {"text": "Unused endpoint: GET /available"}, "properties": {"repobilityId": "99a14e02cfc78d6e", "scanner": "scanner-primary", "fingerprint": "4ba3ea8eb248030a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-18a4887e7bea6b36", "level": "note", "message": {"text": "Unused endpoint: GET /compare"}, "properties": {"repobilityId": "03e2e8f3350cd6f2", "scanner": "scanner-primary", "fingerprint": "18a4887e7bea6b36", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8f9421ca9c1482a4", "level": "note", "message": {"text": "Unused endpoint: GET /{key:path}"}, "properties": {"repobilityId": "8cdc76824dfe4fa7", "scanner": "scanner-primary", "fingerprint": "8f9421ca9c1482a4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-670c07fb91c2a5c3", "level": "note", "message": {"text": "Unused endpoint: GET /states"}, "properties": {"repobilityId": "dca0d44577e29833", "scanner": "scanner-primary", "fingerprint": "670c07fb91c2a5c3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cf366c191e669ea4", "level": "note", "message": {"text": "Unused endpoint: GET /state/{state}/summary"}, "properties": {"repobilityId": "db66e0392bfbab4a", "scanner": "scanner-primary", "fingerprint": "cf366c191e669ea4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-46c51608ce01a149", "level": "note", "message": {"text": "Unused endpoint: GET /state/{state}/entries"}, "properties": {"repobilityId": "4fa39fc71ecb08ab", "scanner": "scanner-primary", "fingerprint": "46c51608ce01a149", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9e73537db9bbcc43", "level": "note", "message": {"text": "Unused endpoint: GET /voyager/{name}"}, "properties": {"repobilityId": "4f140e93b7ab31bd", "scanner": "scanner-primary", "fingerprint": "9e73537db9bbcc43", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ba4c47f2c44052b", "level": "note", "message": {"text": "Unused endpoint: GET /top-by-era"}, "properties": {"repobilityId": "bdb4558e2ca52617", "scanner": "scanner-primary", "fingerprint": "0ba4c47f2c44052b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5272c40f73375d7a", "level": "note", "message": {"text": "Unused endpoint: GET /yl-index"}, "properties": {"repobilityId": "8ef5479744f2693d", "scanner": "scanner-primary", "fingerprint": "5272c40f73375d7a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}