{"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-a7b3db9745e9c497", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ui/chart.tsx:81", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ui/chart.tsx:81"}, "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-4bdc97225fcd6e87", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/FeedCard.tsx:204", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/FeedCard.tsx:204"}, "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-4892985989b92758", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourceActivityPanel.tsx:48", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourceActivityPanel.tsx:48"}, "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-d3a400d0c18abba5", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourceIntelPanel.tsx:98", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourceIntelPanel.tsx:98"}, "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-5c152f0cd39de16f", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/Sidebar.tsx:129", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/Sidebar.tsx:129"}, "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-b1b463cbfb5e2a3e", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/FeedHealthBanner.tsx:75", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/FeedHealthBanner.tsx:75"}, "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-a31af4720e156563", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourcesSheet.tsx:260", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourcesSheet.tsx:260"}, "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-484198fd2e207c76", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/CategoryDistribution.tsx:22", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/CategoryDistribution.tsx:22"}, "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-01c58ceff3d5f673", "name": "Stray `console.log` in TS/JS \u2014 scripts/backfill-embeddings.ts:59", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-embeddings.ts:59"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-404ef78e928f0aee", "name": "Stray `console.log` in TS/JS \u2014 scripts/purge-demo-data.ts:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/purge-demo-data.ts:32"}, "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-a1f0a31a1cf246ac", "name": "Stray `console.log` in TS/JS \u2014 script/build.ts:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 script/build.ts:25"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-69afdf653e6a4a00", "name": "Stray `console.log` in TS/JS \u2014 server/briefing.ts:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/briefing.ts:35"}, "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-c7f93ef8981c65dd", "name": "Stray `console.log` in TS/JS \u2014 server/index.ts:91", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/index.ts:91"}, "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-f9222ce9e4036c2d", "name": "Stray `console.log` in TS/JS \u2014 server/feedEngine.ts:261", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/feedEngine.ts:261"}, "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-a5c98a227642e4be", "name": "Stray `console.log` in TS/JS \u2014 server/routes.ts:173", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/routes.ts:173"}, "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-cb0fb4996a022532", "name": "Stray `console.log` in TS/JS \u2014 server/migrate.ts:42", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/migrate.ts:42"}, "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-ec317d573413aacb", "name": "Stray `console.log` in TS/JS \u2014 server/clustering.ts:48", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/clustering.ts:48"}, "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-e5e8f676c7e290c1", "name": "Stray `console.log` in TS/JS \u2014 server/brief.ts:175", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/brief.ts:175"}, "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-15754687def44b71", "name": "Stray `console.log` in TS/JS \u2014 server/priority.ts:125", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/priority.ts:125"}, "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-606d987c5deb6d8e", "name": "Stray `console.log` in TS/JS \u2014 server/digest.ts:106", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/digest.ts:106"}, "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-8987d6d1c30c7202", "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-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8df37d9232a59094", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ui/chart.tsx:81", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ui/chart.tsx:81"}, "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-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-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 30 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 13 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-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-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-6599f64480a00d39", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/queryClient.ts:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/queryClient.ts:17"}, "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-28f14759086855e4", "name": "Commented-code block (7 lines) in shared/constants.ts:11", "shortDescription": {"text": "Commented-code block (7 lines) in shared/constants.ts:11"}, "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-4f7a69a7a9432096", "name": "Commented-code block (6 lines) in server/storage.ts:681", "shortDescription": {"text": "Commented-code block (6 lines) in server/storage.ts:681"}, "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-2add12fb93ee1fc3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/deliver.ts:116", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/deliver.ts:116"}, "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-5ffdd6c8a62e5bbb", "name": "Commented-code block (6 lines) in server/feedEngine.ts:58", "shortDescription": {"text": "Commented-code block (6 lines) in server/feedEngine.ts:58"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b65a591b9293bbe1", "name": "Commented-code block (7 lines) in server/ssrfGuard.ts:5", "shortDescription": {"text": "Commented-code block (7 lines) in server/ssrfGuard.ts:5"}, "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-06ce3480e21a3d5b", "name": "Commented-code block (5 lines) in server/routes.ts:119", "shortDescription": {"text": "Commented-code block (5 lines) in server/routes.ts:119"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-31e641728497acad", "name": "Commented-code block (5 lines) in server/brief.ts:20", "shortDescription": {"text": "Commented-code block (5 lines) in server/brief.ts:20"}, "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-f36a9b324905af6f", "name": "Unused endpoint: USE /{*path}", "shortDescription": {"text": "Unused endpoint: USE /{*path}"}, "fullDescription": {"text": "`server/static.ts` declares `USE /{*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-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`server/index.ts` declares `USE /api` 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-57433008229e5f34", "name": "Unused endpoint: USE /api/feed/refresh", "shortDescription": {"text": "Unused endpoint: USE /api/feed/refresh"}, "fullDescription": {"text": "`server/index.ts` declares `USE /api/feed/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-4756b4c4da7d2088", "name": "Unused endpoint: GET /api/health", "shortDescription": {"text": "Unused endpoint: GET /api/health"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/health` 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-05d46f103a343922", "name": "Unused endpoint: GET /api/feed", "shortDescription": {"text": "Unused endpoint: GET /api/feed"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/feed` 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-3b37265900e79a8a", "name": "Unused endpoint: GET /api/stats", "shortDescription": {"text": "Unused endpoint: GET /api/stats"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/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-b9a7174b442f86c9", "name": "Unused endpoint: POST /api/feed/refresh", "shortDescription": {"text": "Unused endpoint: POST /api/feed/refresh"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/feed/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-2bb3fd5a015dfc13", "name": "Unused endpoint: POST /api/items/read", "shortDescription": {"text": "Unused endpoint: POST /api/items/read"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/items/read` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-348d86e9e0dcf1c9", "name": "Unused endpoint: POST /api/feed/read-all", "shortDescription": {"text": "Unused endpoint: POST /api/feed/read-all"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/feed/read-all` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-567bd4ce6425cc01", "name": "Unused endpoint: GET /api/items/:id/cluster", "shortDescription": {"text": "Unused endpoint: GET /api/items/:id/cluster"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/items/:id/cluster` 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-f9f23af6a4b1eaf3", "name": "Unused endpoint: GET /api/items/:id/related", "shortDescription": {"text": "Unused endpoint: GET /api/items/:id/related"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/items/:id/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-11e6fefd85ed5654", "name": "Unused endpoint: GET /api/sources/activity", "shortDescription": {"text": "Unused endpoint: GET /api/sources/activity"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/sources/activity` 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-80dc74c12e891358", "name": "Unused endpoint: GET /api/sources/intel", "shortDescription": {"text": "Unused endpoint: GET /api/sources/intel"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/sources/intel` 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-3c92dcd83586806b", "name": "Unused endpoint: GET /api/sources/health", "shortDescription": {"text": "Unused endpoint: GET /api/sources/health"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/sources/health` 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-83b35a5a43f6f471", "name": "Unused endpoint: GET /api/sources", "shortDescription": {"text": "Unused endpoint: GET /api/sources"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/sources` 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-2f560e03ed234dca", "name": "Unused endpoint: POST /api/sources", "shortDescription": {"text": "Unused endpoint: POST /api/sources"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/sources` 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-6e5d8e1a57964131", "name": "Unused endpoint: PATCH /api/sources/:id", "shortDescription": {"text": "Unused endpoint: PATCH /api/sources/:id"}, "fullDescription": {"text": "`server/routes.ts` declares `PATCH /api/sources/: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-a6b4285b486e71e5", "name": "Unused endpoint: DELETE /api/sources/:id", "shortDescription": {"text": "Unused endpoint: DELETE /api/sources/:id"}, "fullDescription": {"text": "`server/routes.ts` declares `DELETE /api/sources/: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-84df4fcf2cbe5117", "name": "Unused endpoint: GET /api/briefing", "shortDescription": {"text": "Unused endpoint: GET /api/briefing"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/briefing` 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-436e0bef321b162a", "name": "Unused endpoint: POST /api/briefing/regenerate", "shortDescription": {"text": "Unused endpoint: POST /api/briefing/regenerate"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/briefing/regenerate` 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-0ce679be5efdaec3", "name": "Unused endpoint: GET /api/briefings", "shortDescription": {"text": "Unused endpoint: GET /api/briefings"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/briefings` 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-c55f749f6c08ce04", "name": "Unused endpoint: GET /api/brief/draft", "shortDescription": {"text": "Unused endpoint: GET /api/brief/draft"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/brief/draft` 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-05bd5615251ea12c", "name": "Unused endpoint: POST /api/brief/generate", "shortDescription": {"text": "Unused endpoint: POST /api/brief/generate"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/brief/generate` 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-b1763faf400df367", "name": "Unused endpoint: PATCH /api/brief/:id", "shortDescription": {"text": "Unused endpoint: PATCH /api/brief/:id"}, "fullDescription": {"text": "`server/routes.ts` declares `PATCH /api/brief/: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-82c9e906bd2c278f", "name": "Unused endpoint: POST /api/brief/:id/approve", "shortDescription": {"text": "Unused endpoint: POST /api/brief/:id/approve"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/brief/:id/approve` 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-e21f669c7e20e418", "name": "Unused endpoint: GET /api/watchlists", "shortDescription": {"text": "Unused endpoint: GET /api/watchlists"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/watchlists` 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-65f913bd6010442a", "name": "Unused endpoint: POST /api/watchlists", "shortDescription": {"text": "Unused endpoint: POST /api/watchlists"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/watchlists` 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-401ed41f348e8c9e", "name": "Unused endpoint: PATCH /api/watchlists/:id", "shortDescription": {"text": "Unused endpoint: PATCH /api/watchlists/:id"}, "fullDescription": {"text": "`server/routes.ts` declares `PATCH /api/watchlists/: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-eb3105e6a73c63fc", "name": "Unused endpoint: DELETE /api/watchlists/:id", "shortDescription": {"text": "Unused endpoint: DELETE /api/watchlists/:id"}, "fullDescription": {"text": "`server/routes.ts` declares `DELETE /api/watchlists/: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-dfd015a2666bd8cf", "name": "Unused endpoint: GET /api/bookmarks", "shortDescription": {"text": "Unused endpoint: GET /api/bookmarks"}, "fullDescription": {"text": "`server/routes.ts` declares `GET /api/bookmarks` 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-ca1735fa8958adfb", "name": "Unused endpoint: POST /api/bookmarks", "shortDescription": {"text": "Unused endpoint: POST /api/bookmarks"}, "fullDescription": {"text": "`server/routes.ts` declares `POST /api/bookmarks` 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-9590e511ba98ea3c", "name": "Unused endpoint: DELETE /api/bookmarks/:feedItemId", "shortDescription": {"text": "Unused endpoint: DELETE /api/bookmarks/:feedItemId"}, "fullDescription": {"text": "`server/routes.ts` declares `DELETE /api/bookmarks/:feedItemId` 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/21078"}, "properties": {"repository": "thechrisgrey/ai-noc", "repoUrl": "https://github.com/thechrisgrey/ai-noc", "branch": "main"}, "results": [{"ruleId": "scanner-a7b3db9745e9c497", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ui/chart.tsx:81"}, "properties": {"repobilityId": "1c3a04e593515dbe", "scanner": "scanner-primary", "fingerprint": "a7b3db9745e9c497", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-4bdc97225fcd6e87", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/FeedCard.tsx:204"}, "properties": {"repobilityId": "f2b3c30c03569183", "scanner": "scanner-primary", "fingerprint": "4bdc97225fcd6e87", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4892985989b92758", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourceActivityPanel.tsx:48"}, "properties": {"repobilityId": "02d5699493d381c6", "scanner": "scanner-primary", "fingerprint": "4892985989b92758", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d3a400d0c18abba5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourceIntelPanel.tsx:98"}, "properties": {"repobilityId": "a0f7a5728c268998", "scanner": "scanner-primary", "fingerprint": "d3a400d0c18abba5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5c152f0cd39de16f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/Sidebar.tsx:129"}, "properties": {"repobilityId": "a5b9ef20c6a77b38", "scanner": "scanner-primary", "fingerprint": "5c152f0cd39de16f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b1b463cbfb5e2a3e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/FeedHealthBanner.tsx:75"}, "properties": {"repobilityId": "fbe7435b1e827f45", "scanner": "scanner-primary", "fingerprint": "b1b463cbfb5e2a3e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a31af4720e156563", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/SourcesSheet.tsx:260"}, "properties": {"repobilityId": "ff94a8e9f1318b12", "scanner": "scanner-primary", "fingerprint": "a31af4720e156563", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-484198fd2e207c76", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/dashboard/CategoryDistribution.tsx:22"}, "properties": {"repobilityId": "041e9506a9872614", "scanner": "scanner-primary", "fingerprint": "484198fd2e207c76", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-01c58ceff3d5f673", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/backfill-embeddings.ts:59"}, "properties": {"repobilityId": "bf4662e64bf6c75a", "scanner": "scanner-primary", "fingerprint": "01c58ceff3d5f673", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-404ef78e928f0aee", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/purge-demo-data.ts:32"}, "properties": {"repobilityId": "03d205d21b8d5fcf", "scanner": "scanner-primary", "fingerprint": "404ef78e928f0aee", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a1f0a31a1cf246ac", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 script/build.ts:25"}, "properties": {"repobilityId": "47ceeaa6313fa094", "scanner": "scanner-primary", "fingerprint": "a1f0a31a1cf246ac", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-69afdf653e6a4a00", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/briefing.ts:35"}, "properties": {"repobilityId": "face85beacbf486b", "scanner": "scanner-primary", "fingerprint": "69afdf653e6a4a00", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c7f93ef8981c65dd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/index.ts:91"}, "properties": {"repobilityId": "b4961a877930fd2f", "scanner": "scanner-primary", "fingerprint": "c7f93ef8981c65dd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f9222ce9e4036c2d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/feedEngine.ts:261"}, "properties": {"repobilityId": "88b7e58b1bcf67f3", "scanner": "scanner-primary", "fingerprint": "f9222ce9e4036c2d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a5c98a227642e4be", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/routes.ts:173"}, "properties": {"repobilityId": "0bee57c0b23c9def", "scanner": "scanner-primary", "fingerprint": "a5c98a227642e4be", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cb0fb4996a022532", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/migrate.ts:42"}, "properties": {"repobilityId": "47589488b2e92ffa", "scanner": "scanner-primary", "fingerprint": "cb0fb4996a022532", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ec317d573413aacb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/clustering.ts:48"}, "properties": {"repobilityId": "1d34c6f82fc87155", "scanner": "scanner-primary", "fingerprint": "ec317d573413aacb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e5e8f676c7e290c1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/brief.ts:175"}, "properties": {"repobilityId": "ce78938171bed4ea", "scanner": "scanner-primary", "fingerprint": "e5e8f676c7e290c1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-15754687def44b71", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/priority.ts:125"}, "properties": {"repobilityId": "3d08e41f4540bb4f", "scanner": "scanner-primary", "fingerprint": "15754687def44b71", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-606d987c5deb6d8e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/digest.ts:106"}, "properties": {"repobilityId": "8668929bc7528dd1", "scanner": "scanner-primary", "fingerprint": "606d987c5deb6d8e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8987d6d1c30c7202", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "d35f8b30360843b0", "scanner": "scanner-primary", "fingerprint": "8987d6d1c30c7202", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-8987d6d1c30c7202", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "d9feb8a3a7b0f1bb", "scanner": "scanner-primary", "fingerprint": "8987d6d1c30c7202", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 13}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-8df37d9232a59094", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ui/chart.tsx:81"}, "properties": {"repobilityId": "298aaf10501f50f1", "scanner": "scanner-primary", "fingerprint": "8df37d9232a59094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/ui/chart.tsx"}, "region": {"startLine": 81}}}]}, {"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-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "0dc026096a364fd7", "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": "42ffb820cd6c9f01", "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": "c044a7922e3ad381", "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": "e2bb5783abcb710d", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "04adb62638d5922f", "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": "fdb86501685bd1a0", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-6599f64480a00d39", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/queryClient.ts:17"}, "properties": {"repobilityId": "9ff936897c0dba7b", "scanner": "scanner-primary", "fingerprint": "6599f64480a00d39", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-28f14759086855e4", "level": "none", "message": {"text": "Commented-code block (7 lines) in shared/constants.ts:11"}, "properties": {"repobilityId": "6b6f02073ac2f046", "scanner": "scanner-primary", "fingerprint": "28f14759086855e4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4f7a69a7a9432096", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/storage.ts:681"}, "properties": {"repobilityId": "57d0e0eddfda9ad7", "scanner": "scanner-primary", "fingerprint": "4f7a69a7a9432096", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2add12fb93ee1fc3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/deliver.ts:116"}, "properties": {"repobilityId": "e8f6c913099d71b6", "scanner": "scanner-primary", "fingerprint": "2add12fb93ee1fc3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5ffdd6c8a62e5bbb", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/feedEngine.ts:58"}, "properties": {"repobilityId": "ed3b9c342cff8e39", "scanner": "scanner-primary", "fingerprint": "5ffdd6c8a62e5bbb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b65a591b9293bbe1", "level": "none", "message": {"text": "Commented-code block (7 lines) in server/ssrfGuard.ts:5"}, "properties": {"repobilityId": "08362ed155ba4f86", "scanner": "scanner-primary", "fingerprint": "b65a591b9293bbe1", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-06ce3480e21a3d5b", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/routes.ts:119"}, "properties": {"repobilityId": "ab6879874a601f80", "scanner": "scanner-primary", "fingerprint": "06ce3480e21a3d5b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-31e641728497acad", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/brief.ts:20"}, "properties": {"repobilityId": "0de23541e020118c", "scanner": "scanner-primary", "fingerprint": "31e641728497acad", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f36a9b324905af6f", "level": "note", "message": {"text": "Unused endpoint: USE /{*path}"}, "properties": {"repobilityId": "8d925892047c5a7a", "scanner": "scanner-primary", "fingerprint": "f36a9b324905af6f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "0a86e1e7408d17f7", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-57433008229e5f34", "level": "note", "message": {"text": "Unused endpoint: USE /api/feed/refresh"}, "properties": {"repobilityId": "a5140486a81a99db", "scanner": "scanner-primary", "fingerprint": "57433008229e5f34", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4756b4c4da7d2088", "level": "note", "message": {"text": "Unused endpoint: GET /api/health"}, "properties": {"repobilityId": "54492c2b662dbb0c", "scanner": "scanner-primary", "fingerprint": "4756b4c4da7d2088", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-05d46f103a343922", "level": "note", "message": {"text": "Unused endpoint: GET /api/feed"}, "properties": {"repobilityId": "34321629db6e1e30", "scanner": "scanner-primary", "fingerprint": "05d46f103a343922", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b37265900e79a8a", "level": "note", "message": {"text": "Unused endpoint: GET /api/stats"}, "properties": {"repobilityId": "41127a7b648409c3", "scanner": "scanner-primary", "fingerprint": "3b37265900e79a8a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b9a7174b442f86c9", "level": "note", "message": {"text": "Unused endpoint: POST /api/feed/refresh"}, "properties": {"repobilityId": "893ef6401d2b36c5", "scanner": "scanner-primary", "fingerprint": "b9a7174b442f86c9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2bb3fd5a015dfc13", "level": "note", "message": {"text": "Unused endpoint: POST /api/items/read"}, "properties": {"repobilityId": "a63de7562f9c078b", "scanner": "scanner-primary", "fingerprint": "2bb3fd5a015dfc13", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-348d86e9e0dcf1c9", "level": "note", "message": {"text": "Unused endpoint: POST /api/feed/read-all"}, "properties": {"repobilityId": "a443758e3505b4ec", "scanner": "scanner-primary", "fingerprint": "348d86e9e0dcf1c9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-567bd4ce6425cc01", "level": "note", "message": {"text": "Unused endpoint: GET /api/items/:id/cluster"}, "properties": {"repobilityId": "1ba599c902eafbe0", "scanner": "scanner-primary", "fingerprint": "567bd4ce6425cc01", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f9f23af6a4b1eaf3", "level": "note", "message": {"text": "Unused endpoint: GET /api/items/:id/related"}, "properties": {"repobilityId": "363b00c7f459acce", "scanner": "scanner-primary", "fingerprint": "f9f23af6a4b1eaf3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-11e6fefd85ed5654", "level": "note", "message": {"text": "Unused endpoint: GET /api/sources/activity"}, "properties": {"repobilityId": "a41e46da4aacf366", "scanner": "scanner-primary", "fingerprint": "11e6fefd85ed5654", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-80dc74c12e891358", "level": "note", "message": {"text": "Unused endpoint: GET /api/sources/intel"}, "properties": {"repobilityId": "9cb55b6cab3aa3c6", "scanner": "scanner-primary", "fingerprint": "80dc74c12e891358", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3c92dcd83586806b", "level": "note", "message": {"text": "Unused endpoint: GET /api/sources/health"}, "properties": {"repobilityId": "bc3be10a8032c8fb", "scanner": "scanner-primary", "fingerprint": "3c92dcd83586806b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-83b35a5a43f6f471", "level": "note", "message": {"text": "Unused endpoint: GET /api/sources"}, "properties": {"repobilityId": "40971def19aea3bf", "scanner": "scanner-primary", "fingerprint": "83b35a5a43f6f471", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2f560e03ed234dca", "level": "note", "message": {"text": "Unused endpoint: POST /api/sources"}, "properties": {"repobilityId": "0f19e660734cead5", "scanner": "scanner-primary", "fingerprint": "2f560e03ed234dca", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6e5d8e1a57964131", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/sources/:id"}, "properties": {"repobilityId": "01e37f1e71d74bea", "scanner": "scanner-primary", "fingerprint": "6e5d8e1a57964131", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a6b4285b486e71e5", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/sources/:id"}, "properties": {"repobilityId": "de863427faf11c78", "scanner": "scanner-primary", "fingerprint": "a6b4285b486e71e5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-84df4fcf2cbe5117", "level": "note", "message": {"text": "Unused endpoint: GET /api/briefing"}, "properties": {"repobilityId": "2ed6bf383b01acc4", "scanner": "scanner-primary", "fingerprint": "84df4fcf2cbe5117", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-436e0bef321b162a", "level": "note", "message": {"text": "Unused endpoint: POST /api/briefing/regenerate"}, "properties": {"repobilityId": "3dc6deb67d8ca84f", "scanner": "scanner-primary", "fingerprint": "436e0bef321b162a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ce679be5efdaec3", "level": "note", "message": {"text": "Unused endpoint: GET /api/briefings"}, "properties": {"repobilityId": "8028752cc83d9056", "scanner": "scanner-primary", "fingerprint": "0ce679be5efdaec3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c55f749f6c08ce04", "level": "note", "message": {"text": "Unused endpoint: GET /api/brief/draft"}, "properties": {"repobilityId": "ccaebc799192554d", "scanner": "scanner-primary", "fingerprint": "c55f749f6c08ce04", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-05bd5615251ea12c", "level": "note", "message": {"text": "Unused endpoint: POST /api/brief/generate"}, "properties": {"repobilityId": "417d4f3cc3f0e20b", "scanner": "scanner-primary", "fingerprint": "05bd5615251ea12c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b1763faf400df367", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/brief/:id"}, "properties": {"repobilityId": "a06c08322b5e4b7f", "scanner": "scanner-primary", "fingerprint": "b1763faf400df367", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-82c9e906bd2c278f", "level": "note", "message": {"text": "Unused endpoint: POST /api/brief/:id/approve"}, "properties": {"repobilityId": "efea959f670617c0", "scanner": "scanner-primary", "fingerprint": "82c9e906bd2c278f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e21f669c7e20e418", "level": "note", "message": {"text": "Unused endpoint: GET /api/watchlists"}, "properties": {"repobilityId": "64d4c0eafe621a8a", "scanner": "scanner-primary", "fingerprint": "e21f669c7e20e418", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-65f913bd6010442a", "level": "note", "message": {"text": "Unused endpoint: POST /api/watchlists"}, "properties": {"repobilityId": "4df2d4333e77c5af", "scanner": "scanner-primary", "fingerprint": "65f913bd6010442a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-401ed41f348e8c9e", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/watchlists/:id"}, "properties": {"repobilityId": "be093ff3519a0284", "scanner": "scanner-primary", "fingerprint": "401ed41f348e8c9e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-eb3105e6a73c63fc", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/watchlists/:id"}, "properties": {"repobilityId": "56c8351b8d68c413", "scanner": "scanner-primary", "fingerprint": "eb3105e6a73c63fc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dfd015a2666bd8cf", "level": "note", "message": {"text": "Unused endpoint: GET /api/bookmarks"}, "properties": {"repobilityId": "2a81126ac10ddaab", "scanner": "scanner-primary", "fingerprint": "dfd015a2666bd8cf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca1735fa8958adfb", "level": "note", "message": {"text": "Unused endpoint: POST /api/bookmarks"}, "properties": {"repobilityId": "9d9bc36e0e37ee27", "scanner": "scanner-primary", "fingerprint": "ca1735fa8958adfb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9590e511ba98ea3c", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/bookmarks/:feedItemId"}, "properties": {"repobilityId": "a4d028cd8144a90a", "scanner": "scanner-primary", "fingerprint": "9590e511ba98ea3c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}