{"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-adec7eff08b32b81", "name": "Possibly dead Python function: utcnow", "shortDescription": {"text": "Possibly dead Python function: utcnow"}, "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-917508cea94aca60", "name": "Possibly dead Python function: new_uuid", "shortDescription": {"text": "Possibly dead Python function: new_uuid"}, "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-79dbc0303c04e6d7", "name": "Possibly dead Python function: send_wrapper", "shortDescription": {"text": "Possibly dead Python function: send_wrapper"}, "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-4c74464065f1de1b", "name": "Possibly dead Python function: to_iso_z", "shortDescription": {"text": "Possibly dead Python function: to_iso_z"}, "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-c0aec69763340904", "name": "Possibly dead Python function: upgrade", "shortDescription": {"text": "Possibly dead Python function: upgrade"}, "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-b68b56edc09d7e36", "name": "Possibly dead Python function: downgrade", "shortDescription": {"text": "Possibly dead Python function: downgrade"}, "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-b91d6c4e44b43651", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/AppShell.tsx:61", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/AppShell.tsx:61"}, "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-34668ad261af8bdf", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/chat/ModelSelector.tsx:42", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/chat/ModelSelector.tsx:42"}, "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-d0921066ccca1d5d", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/providers/ProviderCard.tsx:41", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/providers/ProviderCard.tsx:41"}, "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-1f143a9c3e66104c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/home/WikiPanel.tsx:79", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/home/WikiPanel.tsx:79"}, "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-1f50f2546af7800a", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/home/SourcePanel.tsx:73", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/home/SourcePanel.tsx:73"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-33a20e4e104aee11", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/ChatPage.tsx:91", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/ChatPage.tsx:91"}, "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-60427b03771411b6", "name": "Dockerfile runs as root: frontend/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-faa134129e5545ff", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b048d166901fd868", "name": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "13 test file(s) for 150 source file(s) (ratio 0.09). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-72b2a6250083a784", "name": "Placeholder or mock-heavy implementation detected", "shortDescription": {"text": "Placeholder or mock-heavy implementation detected"}, "fullDescription": {"text": "Found 15 placeholder/mock markers across 6 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-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7776507525266f4c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api/client.ts:97", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api/client.ts: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-6a3d48b461276c63", "name": "Legacy-named symbol `list_objects_v2` in backend/app/services/object_storage/s3.py:126", "shortDescription": {"text": "Legacy-named symbol `list_objects_v2` in backend/app/services/object_storage/s3.py:126"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-be46ea126aa5d8dc", "name": "Near-duplicate function bodies in 3 places", "shortDescription": {"text": "Near-duplicate function bodies in 3 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/services/cache/base.py:delete, backend/app/services/vector_db/base.py:drop_collection, backend/app/services/object_storage/base.py:list_objects\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/services/vector_db/elasticsearch.py:ensure_collection, backend/app/services/vector_db/opensearch.py:ensure_collection\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-33a6b62e30ce7ab4", "name": "Near-duplicate function bodies in 6 places", "shortDescription": {"text": "Near-duplicate function bodies in 6 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nbackend/app/services/vector_db/elasticsearch.py:search, backend/app/services/vector_db/opensearch.py:search, backend/app/services/vector_db/tencent.py:search, backend/app/services/vector_db/pgvecto_rs.py:search\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-87a039194a4bee16", "name": "FastAPI POST `create_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:18", "shortDescription": {"text": "FastAPI POST `create_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:18"}, "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-feeed5c9036778f5", "name": "FastAPI PATCH `update_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:28", "shortDescription": {"text": "FastAPI PATCH `update_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:28"}, "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-c31a267c0b51da7a", "name": "FastAPI DELETE `delete_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:33", "shortDescription": {"text": "FastAPI DELETE `delete_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:33"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-80a6331ddfb3b80a", "name": "FastAPI POST `test_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:38", "shortDescription": {"text": "FastAPI POST `test_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:38"}, "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-0ee5089df563cdfa", "name": "FastAPI POST `refresh_models` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:43", "shortDescription": {"text": "FastAPI POST `refresh_models` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:43"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-900ca57f47616a43", "name": "FastAPI POST `lint_wiki` without auth dependency \u2014 backend/app/api/v1/wiki.py:23", "shortDescription": {"text": "FastAPI POST `lint_wiki` without auth dependency \u2014 backend/app/api/v1/wiki.py:23"}, "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-f970ddf69e195234", "name": "FastAPI POST `create_conversation` without auth dependency \u2014 backend/app/api/v1/conversations.py:19", "shortDescription": {"text": "FastAPI POST `create_conversation` without auth dependency \u2014 backend/app/api/v1/conversations.py:19"}, "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-045a58c643fcd732", "name": "FastAPI DELETE `delete_conversation` without auth dependency \u2014 backend/app/api/v1/conversations.py:29", "shortDescription": {"text": "FastAPI DELETE `delete_conversation` without auth dependency \u2014 backend/app/api/v1/conversations.py:29"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-af7ccf01b30df010", "name": "FastAPI POST `post_message` without auth dependency \u2014 backend/app/api/v1/conversations.py:40", "shortDescription": {"text": "FastAPI POST `post_message` without auth dependency \u2014 backend/app/api/v1/conversations.py:40"}, "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-29c16cfad6a8c9f8", "name": "FastAPI POST `upload_source` without auth dependency \u2014 backend/app/api/v1/sources.py:18", "shortDescription": {"text": "FastAPI POST `upload_source` without auth dependency \u2014 backend/app/api/v1/sources.py:18"}, "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-3a51407802b954eb", "name": "FastAPI DELETE `delete_source` without auth dependency \u2014 backend/app/api/v1/sources.py:42", "shortDescription": {"text": "FastAPI DELETE `delete_source` without auth dependency \u2014 backend/app/api/v1/sources.py:42"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7f986d06d8e62556", "name": "FastAPI POST `reingest_source` without auth dependency \u2014 backend/app/api/v1/sources.py:47", "shortDescription": {"text": "FastAPI POST `reingest_source` without auth dependency \u2014 backend/app/api/v1/sources.py:47"}, "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-d87fcc0aa0ed2f55", "name": "FastAPI PATCH `patch_app_settings` without auth dependency \u2014 backend/app/api/v1/settings.py:16", "shortDescription": {"text": "FastAPI PATCH `patch_app_settings` without auth dependency \u2014 backend/app/api/v1/settings.py:16"}, "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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.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-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.py` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-eedcfe28b24c379d", "name": "Unused endpoint: GET /{provider_id}", "shortDescription": {"text": "Unused endpoint: GET /{provider_id}"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.py` declares `GET /{provider_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e67d1fc0874e791e", "name": "Unused endpoint: PATCH /{provider_id}", "shortDescription": {"text": "Unused endpoint: PATCH /{provider_id}"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.py` declares `PATCH /{provider_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b19201f9aaa2467c", "name": "Unused endpoint: DELETE /{provider_id}", "shortDescription": {"text": "Unused endpoint: DELETE /{provider_id}"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.py` declares `DELETE /{provider_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-acdfb02d7a76dde7", "name": "Unused endpoint: POST /{provider_id}/test", "shortDescription": {"text": "Unused endpoint: POST /{provider_id}/test"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.py` declares `POST /{provider_id}/test` 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-f1c8c4ac498fbc8e", "name": "Unused endpoint: POST /{provider_id}/models/refresh", "shortDescription": {"text": "Unused endpoint: POST /{provider_id}/models/refresh"}, "fullDescription": {"text": "`backend/app/api/v1/llm_providers.py` declares `POST /{provider_id}/models/refresh` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-59fb725014e62f30", "name": "Unused endpoint: GET /wiki-pages", "shortDescription": {"text": "Unused endpoint: GET /wiki-pages"}, "fullDescription": {"text": "`backend/app/api/v1/wiki.py` declares `GET /wiki-pages` 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-ef7da47ff1aa9a50", "name": "Unused endpoint: GET /wiki-pages/{slug}", "shortDescription": {"text": "Unused endpoint: GET /wiki-pages/{slug}"}, "fullDescription": {"text": "`backend/app/api/v1/wiki.py` declares `GET /wiki-pages/{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-f01faf8ced7c9a4c", "name": "Unused endpoint: POST /wiki/lint", "shortDescription": {"text": "Unused endpoint: POST /wiki/lint"}, "fullDescription": {"text": "`backend/app/api/v1/wiki.py` declares `POST /wiki/lint` 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-eb4965f4d227f8b3", "name": "Unused endpoint: GET /{conversation_id}", "shortDescription": {"text": "Unused endpoint: GET /{conversation_id}"}, "fullDescription": {"text": "`backend/app/api/v1/conversations.py` declares `GET /{conversation_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ad72d180247f16e2", "name": "Unused endpoint: DELETE /{conversation_id}", "shortDescription": {"text": "Unused endpoint: DELETE /{conversation_id}"}, "fullDescription": {"text": "`backend/app/api/v1/conversations.py` declares `DELETE /{conversation_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-593c6efeb9f4cfb8", "name": "Unused endpoint: GET /{conversation_id}/messages", "shortDescription": {"text": "Unused endpoint: GET /{conversation_id}/messages"}, "fullDescription": {"text": "`backend/app/api/v1/conversations.py` declares `GET /{conversation_id}/messages` 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-5e44869ee7800ad1", "name": "Unused endpoint: POST /{conversation_id}/messages", "shortDescription": {"text": "Unused endpoint: POST /{conversation_id}/messages"}, "fullDescription": {"text": "`backend/app/api/v1/conversations.py` declares `POST /{conversation_id}/messages` 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-1802575e0bd86d08", "name": "Unused endpoint: GET /{source_id}", "shortDescription": {"text": "Unused endpoint: GET /{source_id}"}, "fullDescription": {"text": "`backend/app/api/v1/sources.py` declares `GET /{source_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4fc576f0734db85f", "name": "Unused endpoint: DELETE /{source_id}", "shortDescription": {"text": "Unused endpoint: DELETE /{source_id}"}, "fullDescription": {"text": "`backend/app/api/v1/sources.py` declares `DELETE /{source_id}` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0dfa1e2c4aecfdc9", "name": "Unused endpoint: POST /{source_id}/reingest", "shortDescription": {"text": "Unused endpoint: POST /{source_id}/reingest"}, "fullDescription": {"text": "`backend/app/api/v1/sources.py` declares `POST /{source_id}/reingest` 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-512ccb0fd0b230ba", "name": "Unused endpoint: GET /settings", "shortDescription": {"text": "Unused endpoint: GET /settings"}, "fullDescription": {"text": "`backend/app/api/v1/settings.py` declares `GET /settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-689e4ffd880f570d", "name": "Unused endpoint: PATCH /settings", "shortDescription": {"text": "Unused endpoint: PATCH /settings"}, "fullDescription": {"text": "`backend/app/api/v1/settings.py` declares `PATCH /settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cd8dc4599ec52a08", "name": "Unused endpoint: GET /stats", "shortDescription": {"text": "Unused endpoint: GET /stats"}, "fullDescription": {"text": "`backend/app/api/v1/stats.py` declares `GET /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}}]}}, "automationDetails": {"id": "repobility/23127"}, "properties": {"repository": "yangliubin9-cyber/knowledge-atlas", "repoUrl": "https://github.com/yangliubin9-cyber/knowledge-atlas", "branch": "main"}, "results": [{"ruleId": "scanner-adec7eff08b32b81", "level": "note", "message": {"text": "Possibly dead Python function: utcnow"}, "properties": {"repobilityId": "3764ddf6d1326a6d", "scanner": "scanner-primary", "fingerprint": "adec7eff08b32b81", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/models/base.py:15"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-917508cea94aca60", "level": "note", "message": {"text": "Possibly dead Python function: new_uuid"}, "properties": {"repobilityId": "3f2e93c148ffde9d", "scanner": "scanner-primary", "fingerprint": "917508cea94aca60", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/models/base.py:19"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-79dbc0303c04e6d7", "level": "note", "message": {"text": "Possibly dead Python function: send_wrapper"}, "properties": {"repobilityId": "f34ba48c1fd7571b", "scanner": "scanner-primary", "fingerprint": "79dbc0303c04e6d7", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/core/observability.py:60"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4c74464065f1de1b", "level": "note", "message": {"text": "Possibly dead Python function: to_iso_z"}, "properties": {"repobilityId": "8c76378e32a65b0d", "scanner": "scanner-primary", "fingerprint": "4c74464065f1de1b", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/schemas/common.py:10"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c0aec69763340904", "level": "note", "message": {"text": "Possibly dead Python function: upgrade"}, "properties": {"repobilityId": "cf0b8e5e6e2f8bc4", "scanner": "scanner-primary", "fingerprint": "c0aec69763340904", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/alembic/versions/0001_initial.py:21"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b68b56edc09d7e36", "level": "note", "message": {"text": "Possibly dead Python function: downgrade"}, "properties": {"repobilityId": "c03debbf11efa0c5", "scanner": "scanner-primary", "fingerprint": "b68b56edc09d7e36", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/alembic/versions/0001_initial.py:101"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b91d6c4e44b43651", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/AppShell.tsx:61"}, "properties": {"repobilityId": "b3aaedb852961e71", "scanner": "scanner-primary", "fingerprint": "b91d6c4e44b43651", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-34668ad261af8bdf", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/chat/ModelSelector.tsx:42"}, "properties": {"repobilityId": "2a83e0dcfcc950e3", "scanner": "scanner-primary", "fingerprint": "34668ad261af8bdf", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d0921066ccca1d5d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/providers/ProviderCard.tsx:41"}, "properties": {"repobilityId": "b1a939adce734bd9", "scanner": "scanner-primary", "fingerprint": "d0921066ccca1d5d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1f143a9c3e66104c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/home/WikiPanel.tsx:79"}, "properties": {"repobilityId": "3a7cad68d4bb4008", "scanner": "scanner-primary", "fingerprint": "1f143a9c3e66104c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1f50f2546af7800a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/components/home/SourcePanel.tsx:73"}, "properties": {"repobilityId": "ef1160b07d438fe6", "scanner": "scanner-primary", "fingerprint": "1f50f2546af7800a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-33a20e4e104aee11", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/src/pages/ChatPage.tsx:91"}, "properties": {"repobilityId": "e14c1c449be76309", "scanner": "scanner-primary", "fingerprint": "33a20e4e104aee11", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-60427b03771411b6", "level": "warning", "message": {"text": "Dockerfile runs as root: frontend/Dockerfile"}, "properties": {"repobilityId": "735c01d8531dfd2c", "scanner": "scanner-primary", "fingerprint": "60427b03771411b6", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "14441c073c376e74", "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": 2}}}]}, {"ruleId": "scanner-b048d166901fd868", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: nginx:alpine"}, "properties": {"repobilityId": "0858f21f5e4a708d", "scanner": "scanner-primary", "fingerprint": "b048d166901fd868", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-714c31ca9f474ae6", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "45b7b278889008d0", "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": 3}}}]}, {"ruleId": "scanner-714c31ca9f474ae6", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.12-slim"}, "properties": {"repobilityId": "035b048bbfcfacca", "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": 22}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-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-72b2a6250083a784", "level": "warning", "message": {"text": "Placeholder or mock-heavy implementation detected"}, "properties": {"repobilityId": "748ab16ab92d8cc0", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "21791bfd74964adf", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "702add022555e6b6", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-7776507525266f4c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/src/api/client.ts:97"}, "properties": {"repobilityId": "d4cea9d73cf5c0b5", "scanner": "scanner-primary", "fingerprint": "7776507525266f4c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-6a3d48b461276c63", "level": "note", "message": {"text": "Legacy-named symbol `list_objects_v2` in backend/app/services/object_storage/s3.py:126"}, "properties": {"repobilityId": "46fc080569d344f1", "scanner": "scanner-primary", "fingerprint": "6a3d48b461276c63", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "7bbdd651027217b2", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-be46ea126aa5d8dc", "level": "note", "message": {"text": "Near-duplicate function bodies in 3 places"}, "properties": {"repobilityId": "cd30d9548a19f22a", "scanner": "scanner-primary", "fingerprint": "be46ea126aa5d8dc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "8ba455f51a06e40a", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-33a6b62e30ce7ab4", "level": "note", "message": {"text": "Near-duplicate function bodies in 6 places"}, "properties": {"repobilityId": "6fa3c376dbc9dae7", "scanner": "scanner-primary", "fingerprint": "33a6b62e30ce7ab4", "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": "96889136d976af44", "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": "c480f34f1e7aec94", "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": "6d123c474f91e868", "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": "93e7da77da75a448", "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": "ea11162808f2e00f", "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": "df98479133975ffc", "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": "572189bed551b10a", "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": "21cc4d2efe4066c7", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-87a039194a4bee16", "level": "error", "message": {"text": "FastAPI POST `create_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:18"}, "properties": {"repobilityId": "c84ffb037ea44ba0", "scanner": "scanner-primary", "fingerprint": "87a039194a4bee16", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/llm_providers.py"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-feeed5c9036778f5", "level": "error", "message": {"text": "FastAPI PATCH `update_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:28"}, "properties": {"repobilityId": "2586d359fc5a3c08", "scanner": "scanner-primary", "fingerprint": "feeed5c9036778f5", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/llm_providers.py"}, "region": {"startLine": 28}}}]}, {"ruleId": "scanner-c31a267c0b51da7a", "level": "error", "message": {"text": "FastAPI DELETE `delete_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:33"}, "properties": {"repobilityId": "b42f1e6ab0a7c4db", "scanner": "scanner-primary", "fingerprint": "c31a267c0b51da7a", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/llm_providers.py"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-80a6331ddfb3b80a", "level": "error", "message": {"text": "FastAPI POST `test_provider` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:38"}, "properties": {"repobilityId": "e47eeaf2de03f1ae", "scanner": "scanner-primary", "fingerprint": "80a6331ddfb3b80a", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/llm_providers.py"}, "region": {"startLine": 38}}}]}, {"ruleId": "scanner-0ee5089df563cdfa", "level": "error", "message": {"text": "FastAPI POST `refresh_models` without auth dependency \u2014 backend/app/api/v1/llm_providers.py:43"}, "properties": {"repobilityId": "3b8c7be3479b18c9", "scanner": "scanner-primary", "fingerprint": "0ee5089df563cdfa", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/llm_providers.py"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-900ca57f47616a43", "level": "error", "message": {"text": "FastAPI POST `lint_wiki` without auth dependency \u2014 backend/app/api/v1/wiki.py:23"}, "properties": {"repobilityId": "15c7a4047b11a489", "scanner": "scanner-primary", "fingerprint": "900ca57f47616a43", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/wiki.py"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-f970ddf69e195234", "level": "error", "message": {"text": "FastAPI POST `create_conversation` without auth dependency \u2014 backend/app/api/v1/conversations.py:19"}, "properties": {"repobilityId": "8b6c881d29cde507", "scanner": "scanner-primary", "fingerprint": "f970ddf69e195234", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/conversations.py"}, "region": {"startLine": 19}}}]}, {"ruleId": "scanner-045a58c643fcd732", "level": "error", "message": {"text": "FastAPI DELETE `delete_conversation` without auth dependency \u2014 backend/app/api/v1/conversations.py:29"}, "properties": {"repobilityId": "e447a18911dbf9ab", "scanner": "scanner-primary", "fingerprint": "045a58c643fcd732", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/conversations.py"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-af7ccf01b30df010", "level": "error", "message": {"text": "FastAPI POST `post_message` without auth dependency \u2014 backend/app/api/v1/conversations.py:40"}, "properties": {"repobilityId": "09f72731837786db", "scanner": "scanner-primary", "fingerprint": "af7ccf01b30df010", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/conversations.py"}, "region": {"startLine": 40}}}]}, {"ruleId": "scanner-29c16cfad6a8c9f8", "level": "error", "message": {"text": "FastAPI POST `upload_source` without auth dependency \u2014 backend/app/api/v1/sources.py:18"}, "properties": {"repobilityId": "ffc9d23d4f9808a1", "scanner": "scanner-primary", "fingerprint": "29c16cfad6a8c9f8", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/sources.py"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-3a51407802b954eb", "level": "error", "message": {"text": "FastAPI DELETE `delete_source` without auth dependency \u2014 backend/app/api/v1/sources.py:42"}, "properties": {"repobilityId": "5f721a0b062cda14", "scanner": "scanner-primary", "fingerprint": "3a51407802b954eb", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/sources.py"}, "region": {"startLine": 42}}}]}, {"ruleId": "scanner-7f986d06d8e62556", "level": "error", "message": {"text": "FastAPI POST `reingest_source` without auth dependency \u2014 backend/app/api/v1/sources.py:47"}, "properties": {"repobilityId": "ed01b5cf39241e79", "scanner": "scanner-primary", "fingerprint": "7f986d06d8e62556", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/sources.py"}, "region": {"startLine": 47}}}]}, {"ruleId": "scanner-d87fcc0aa0ed2f55", "level": "error", "message": {"text": "FastAPI PATCH `patch_app_settings` without auth dependency \u2014 backend/app/api/v1/settings.py:16"}, "properties": {"repobilityId": "441464e5867cddcf", "scanner": "scanner-primary", "fingerprint": "d87fcc0aa0ed2f55", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/app/api/v1/settings.py"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "f9b11f1dd9febb25", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "cc99bf27c9790d3c", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eedcfe28b24c379d", "level": "note", "message": {"text": "Unused endpoint: GET /{provider_id}"}, "properties": {"repobilityId": "6c586a57f0f62d2f", "scanner": "scanner-primary", "fingerprint": "eedcfe28b24c379d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e67d1fc0874e791e", "level": "note", "message": {"text": "Unused endpoint: PATCH /{provider_id}"}, "properties": {"repobilityId": "d7b570d18d85f8ff", "scanner": "scanner-primary", "fingerprint": "e67d1fc0874e791e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b19201f9aaa2467c", "level": "note", "message": {"text": "Unused endpoint: DELETE /{provider_id}"}, "properties": {"repobilityId": "1e2e001c46e79a82", "scanner": "scanner-primary", "fingerprint": "b19201f9aaa2467c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-acdfb02d7a76dde7", "level": "note", "message": {"text": "Unused endpoint: POST /{provider_id}/test"}, "properties": {"repobilityId": "0416989044464167", "scanner": "scanner-primary", "fingerprint": "acdfb02d7a76dde7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f1c8c4ac498fbc8e", "level": "note", "message": {"text": "Unused endpoint: POST /{provider_id}/models/refresh"}, "properties": {"repobilityId": "493b361ea4d715cd", "scanner": "scanner-primary", "fingerprint": "f1c8c4ac498fbc8e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-59fb725014e62f30", "level": "note", "message": {"text": "Unused endpoint: GET /wiki-pages"}, "properties": {"repobilityId": "071e4ea022a3a751", "scanner": "scanner-primary", "fingerprint": "59fb725014e62f30", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ef7da47ff1aa9a50", "level": "note", "message": {"text": "Unused endpoint: GET /wiki-pages/{slug}"}, "properties": {"repobilityId": "a5fd8654d236d0a5", "scanner": "scanner-primary", "fingerprint": "ef7da47ff1aa9a50", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f01faf8ced7c9a4c", "level": "note", "message": {"text": "Unused endpoint: POST /wiki/lint"}, "properties": {"repobilityId": "c99d81cb8e11924a", "scanner": "scanner-primary", "fingerprint": "f01faf8ced7c9a4c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eb4965f4d227f8b3", "level": "note", "message": {"text": "Unused endpoint: GET /{conversation_id}"}, "properties": {"repobilityId": "789b3fae6b194fe9", "scanner": "scanner-primary", "fingerprint": "eb4965f4d227f8b3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ad72d180247f16e2", "level": "note", "message": {"text": "Unused endpoint: DELETE /{conversation_id}"}, "properties": {"repobilityId": "2f51dbf6abe9733f", "scanner": "scanner-primary", "fingerprint": "ad72d180247f16e2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-593c6efeb9f4cfb8", "level": "note", "message": {"text": "Unused endpoint: GET /{conversation_id}/messages"}, "properties": {"repobilityId": "e3dc008f650ae64e", "scanner": "scanner-primary", "fingerprint": "593c6efeb9f4cfb8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5e44869ee7800ad1", "level": "note", "message": {"text": "Unused endpoint: POST /{conversation_id}/messages"}, "properties": {"repobilityId": "e0ef495171c1e21b", "scanner": "scanner-primary", "fingerprint": "5e44869ee7800ad1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1802575e0bd86d08", "level": "note", "message": {"text": "Unused endpoint: GET /{source_id}"}, "properties": {"repobilityId": "c6a7c673acf3f420", "scanner": "scanner-primary", "fingerprint": "1802575e0bd86d08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4fc576f0734db85f", "level": "note", "message": {"text": "Unused endpoint: DELETE /{source_id}"}, "properties": {"repobilityId": "2fd63ad888a9e490", "scanner": "scanner-primary", "fingerprint": "4fc576f0734db85f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0dfa1e2c4aecfdc9", "level": "note", "message": {"text": "Unused endpoint: POST /{source_id}/reingest"}, "properties": {"repobilityId": "ca91276c0ac9ac69", "scanner": "scanner-primary", "fingerprint": "0dfa1e2c4aecfdc9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-512ccb0fd0b230ba", "level": "note", "message": {"text": "Unused endpoint: GET /settings"}, "properties": {"repobilityId": "092cc362c12ac1f0", "scanner": "scanner-primary", "fingerprint": "512ccb0fd0b230ba", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-689e4ffd880f570d", "level": "note", "message": {"text": "Unused endpoint: PATCH /settings"}, "properties": {"repobilityId": "c177d21f48075deb", "scanner": "scanner-primary", "fingerprint": "689e4ffd880f570d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cd8dc4599ec52a08", "level": "note", "message": {"text": "Unused endpoint: GET /stats"}, "properties": {"repobilityId": "b80f4555c1396a65", "scanner": "scanner-primary", "fingerprint": "cd8dc4599ec52a08", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}