{"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-8c45cb565fc20606", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/fcm.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/fcm.ts:33"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a8a26f7ab3371296", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/push.ts:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/push.ts:18"}, "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-78301bdc5deb84e3", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/redis.ts:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/redis.ts:17"}, "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-ec5fa7a11f2d6c58", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/db/migrate.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/db/migrate.ts:22"}, "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-f7b6280fd4074fa8", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/db/manualMigrate.ts:214", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/db/manualMigrate.ts:214"}, "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-1325d6e696765809", "name": "Stray `console.log` in TS/JS \u2014 apps/web/vite.config.ts:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/web/vite.config.ts:29"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-28314033bf55c840", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/CommandPalette.tsx:108", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/CommandPalette.tsx:108"}, "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-d43dffd620225069", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/Lightbox.tsx:60", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/Lightbox.tsx:60"}, "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-13aa1994de55c3db", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/AppearanceSection.tsx:87", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/AppearanceSection.tsx:87"}, "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-cd1060dbc949c500", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/NameColorsSection.tsx:80", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/NameColorsSection.tsx:80"}, "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-726bc5cc38f3e437", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/WishingStarSection.tsx:16", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/WishingStarSection.tsx:164"}, "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-b1519ae041e56c11", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/MobileMoreSheet.tsx:107", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/MobileMoreSheet.tsx:107"}, "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-383b31d8ed6ac9fd", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/Sidebar.tsx:418", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/Sidebar.tsx:418"}, "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-0a651a01c94af825", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/UserFooter.tsx:59", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/UserFooter.tsx:59"}, "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-ce070100ed3a31a6", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/notifications/NotificationBell.tsx:264", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/notifications/NotificationBell.tsx:264"}, "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-d0fa42e50b9956c7", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/PinnedMessagesSheet.tsx:64", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/PinnedMessagesSheet.tsx:64"}, "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-52bc505e58571a07", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/RecordingDisplay.tsx:47", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/RecordingDisplay.tsx:47"}, "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-cfd06e5e9d2c81e2", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageItem.tsx:780", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageItem.tsx:780"}, "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-e64d3e7fd4a9980c", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/components/chat/CodeBlock.tsx:34", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/components/chat/CodeBlock.tsx:34"}, "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-640a159c701235ad", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageInput.tsx:456", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageInput.tsx:456"}, "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-7cf75700b9908dfc", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/RightPanel.tsx:68", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/RightPanel.tsx:68"}, "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-bfaf96082a38efd6", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageMobileActions.tsx:43", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageMobileActions.tsx:43"}, "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-7fbc753cfe79815c", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/PollCard.tsx:143", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/PollCard.tsx:143"}, "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-9eea185b24856d46", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/Message/MessageAttachments.tsx:163", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/Message/MessageAttachments.tsx:163"}, "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-fad0973823045b96", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/VoiceCallPanel.tsx:109", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/VoiceCallPanel.tsx:109"}, "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-1a4377c994186d23", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/IncomingCallModal.tsx:227", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/IncomingCallModal.tsx:227"}, "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-735f4e4347006007", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/VoiceCallStage.tsx:91", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/VoiceCallStage.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-314513d3fe3b2e03", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/bookmarks/BookmarksSheet.tsx:115", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/bookmarks/BookmarksSheet.tsx:115"}, "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-3ae86fba17773a52", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dm/DMChat.tsx:407", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dm/DMChat.tsx:407"}, "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-5db154b63d74119a", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dm/DMInput.tsx:301", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dm/DMInput.tsx:301"}, "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-b4806427a66f4afa", "name": "Stray `console.log` in TS/JS \u2014 apps/web/src/lib/socket.ts:78", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/web/src/lib/socket.ts:78"}, "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-650bc5d62e1ed675", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/lib/bioMarkdown.tsx:15", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/lib/bioMarkdown.tsx:15"}, "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-aa210a94b4737ecc", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/FriendsPage.tsx:248", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/FriendsPage.tsx:248"}, "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-0175830c86041fc9", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/AppPage.tsx:148", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/AppPage.tsx:148"}, "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-d811eadef2685dbb", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/SettingsPage.tsx:176", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/SettingsPage.tsx:176"}, "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-3f56c41087d804ad", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/DiscoverPage.tsx:89", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/DiscoverPage.tsx:89"}, "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-1a2d3923bf5cba68", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ServerSettingsPage.tsx:226", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ServerSettingsPage.tsx:226"}, "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-26fde097677a2242", "name": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/components/chat/CodeBlock.tsx:34", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/components/chat/CodeBlock.tsx:34"}, "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-05733e84e65ab0e3", "name": "Insecure pattern 'node_child_process' in scripts/predev.mjs:16", "shortDescription": {"text": "Insecure pattern 'node_child_process' in scripts/predev.mjs:16"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/setup-node@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8f554d346d2e7c3c", "name": "Very large file: apps/web/src/pages/ServerSettingsPage.tsx (1557 lines)", "shortDescription": {"text": "Very large file: apps/web/src/pages/ServerSettingsPage.tsx (1557 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "9 test file(s) for 276 source file(s) (ratio 0.03). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b06b8d86f24c77f9", "name": "Node manifest has dependencies but no lockfile: apps/api/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cb3e52667c84fb86", "name": "Node manifest has dependencies but no lockfile: packages/types/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/types/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "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 21 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 70 placeholder/mock markers across 38 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-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "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-efe11740f28539d9", "name": "Commented-code block (5 lines) in apps/api/src/index.ts:63", "shortDescription": {"text": "Commented-code block (5 lines) in apps/api/src/index.ts:63"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-aef0074efbffe697", "name": "Commented-code block (5 lines) in apps/api/src/config/passport.ts:40", "shortDescription": {"text": "Commented-code block (5 lines) in apps/api/src/config/passport.ts:40"}, "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-34c8cb9721bc0a5c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/bot.ts:318", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/bot.ts:318"}, "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-bc25e97ce44da496", "name": "Commented-code block (5 lines) in apps/api/src/routes/auth.ts:45", "shortDescription": {"text": "Commented-code block (5 lines) in apps/api/src/routes/auth.ts:45"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-cd1bfe4a802f269a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/gif.ts:68", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/gif.ts:68"}, "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-59ff985a9cbbd046", "name": "Commented-code block (5 lines) in apps/web/src/components/layout/Sidebar.tsx:226", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/components/layout/Sidebar.tsx:226"}, "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-c18e7adbbc112893", "name": "Commented-code block (5 lines) in apps/web/src/components/anim/PageTransition.tsx:21", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/components/anim/PageTransition.tsx:21"}, "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-117bd6c6a230d9a7", "name": "Commented-code block (6 lines) in apps/web/src/components/chat/MessageInput.tsx:91", "shortDescription": {"text": "Commented-code block (6 lines) in apps/web/src/components/chat/MessageInput.tsx:91"}, "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-1da2bbe851346cbf", "name": "Commented-code block (5 lines) in apps/web/src/components/chat/MessageList.tsx:270", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/components/chat/MessageList.tsx:270"}, "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-02fdcbe9b45b3a48", "name": "Commented-code block (7 lines) in apps/web/src/lib/api.ts:25", "shortDescription": {"text": "Commented-code block (7 lines) in apps/web/src/lib/api.ts:25"}, "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-c8575c8e7684dda5", "name": "Commented-code block (5 lines) in apps/web/src/hooks/useServerEmojis.tsx:99", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/hooks/useServerEmojis.tsx:99"}, "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-7f41931f64a227fe", "name": "Commented-code block (15 lines) in apps/web/src/store/voiceStore.ts:361", "shortDescription": {"text": "Commented-code block (15 lines) in apps/web/src/store/voiceStore.ts:361"}, "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-cc0f9d8e41b33b0e", "name": "11 env vars used in code but missing from .env.example", "shortDescription": {"text": "11 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ANALYZE`, `CI`, `DEV`, `GITHUB_SHA`, `MODE`, `PROD`, `SENTRY_AUTH_TOKEN`, `SENTRY_ORG` + 3 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-71063a867d727f62", "name": "Frontend route `/auth/callback` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/auth/callback` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c479eee4fb61c1a2", "name": "Frontend route `/invite/:code` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/invite/:code` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a30e97e5b3f0c1a8", "name": "Frontend route `/app/*` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/app/*` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b99ad893b2a77417", "name": "Frontend route `dm/*` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx", "shortDescription": {"text": "Frontend route `dm/*` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d4c797d608e6b90a", "name": "Frontend route `friends` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx", "shortDescription": {"text": "Frontend route `friends` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-48892b57a8d3b82f", "name": "Frontend route `discover` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx", "shortDescription": {"text": "Frontend route `discover` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27150a20000d4b08", "name": "Frontend route `profile` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx", "shortDescription": {"text": "Frontend route `profile` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-71ca81a6210853c8", "name": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx", "shortDescription": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d11c0ef2569762f", "name": "Frontend route `servers/:serverId/settings` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx", "shortDescription": {"text": "Frontend route `servers/:serverId/settings` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7633ffbbbed1a57a", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (apps/api/src/lib/bot.ts:318)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (apps/api/src/lib/bot.ts:318)"}, "fullDescription": {"text": "`apps/api/src/lib/bot.ts:318` calls `POST https://api.anthropic.com/v1/messages` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.anthropic.com/v1/messages`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-7099634488c5d33c", "name": "Dangling fetch: POST https://api.anthropic.com/v1/messages (apps/api/src/routes/translate.ts:66)", "shortDescription": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (apps/api/src/routes/translate.ts:66)"}, "fullDescription": {"text": "`apps/api/src/routes/translate.ts:66` calls `POST https://api.anthropic.com/v1/messages` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.anthropic.com/v1/messages`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-2eeaf8c5695bbc33", "name": "Unused endpoint: USE /api/profile", "shortDescription": {"text": "Unused endpoint: USE /api/profile"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/profile` 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-6eb452fbfb454d20", "name": "Unused endpoint: USE /api/auth", "shortDescription": {"text": "Unused endpoint: USE /api/auth"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/auth` 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-0377ae0651490bdd", "name": "Unused endpoint: USE /api/invites", "shortDescription": {"text": "Unused endpoint: USE /api/invites"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/invites` 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-d320c3433ba04200", "name": "Unused endpoint: USE /i", "shortDescription": {"text": "Unused endpoint: USE /i"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /i` 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-7cccc4aacb62228c", "name": "Unused endpoint: USE /api/servers", "shortDescription": {"text": "Unused endpoint: USE /api/servers"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/servers` 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-0791172e5aa72bb9", "name": "Unused endpoint: USE /api/channels/:channelId/messages", "shortDescription": {"text": "Unused endpoint: USE /api/channels/:channelId/messages"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/channels/:channelId/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-481619cd579b97df", "name": "Unused endpoint: USE /api/channels/:channelId/polls", "shortDescription": {"text": "Unused endpoint: USE /api/channels/:channelId/polls"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/channels/:channelId/polls` 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": "`apps/api/src/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-e2486a74a52b0c2b", "name": "Unused endpoint: USE /api/dm", "shortDescription": {"text": "Unused endpoint: USE /api/dm"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/dm` 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-a74449cc5d561bad", "name": "Unused endpoint: USE /api/search", "shortDescription": {"text": "Unused endpoint: USE /api/search"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/search` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5777abcaa1a80703", "name": "Unused endpoint: USE /api/discover", "shortDescription": {"text": "Unused endpoint: USE /api/discover"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/discover` 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-6f643fbf10ab5803", "name": "Unused endpoint: USE /api/upload", "shortDescription": {"text": "Unused endpoint: USE /api/upload"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/upload` 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-538bbf0ab06b039c", "name": "Unused endpoint: USE /api/push", "shortDescription": {"text": "Unused endpoint: USE /api/push"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/push` 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-de1e931ca2ef126b", "name": "Unused endpoint: USE /api/gif", "shortDescription": {"text": "Unused endpoint: USE /api/gif"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/gif` 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-4ff40cb10f7c8519", "name": "Unused endpoint: USE /api/users", "shortDescription": {"text": "Unused endpoint: USE /api/users"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/users` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-188982f150d29369", "name": "Unused endpoint: USE /api/bookmarks", "shortDescription": {"text": "Unused endpoint: USE /api/bookmarks"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /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-7acee280a96329f0", "name": "Unused endpoint: USE /api/reminders", "shortDescription": {"text": "Unused endpoint: USE /api/reminders"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/reminders` 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-3b4a376810bee148", "name": "Unused endpoint: USE /api/translate", "shortDescription": {"text": "Unused endpoint: USE /api/translate"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/translate` 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-7f6413794dcdf522", "name": "Unused endpoint: USE /api/friends", "shortDescription": {"text": "Unused endpoint: USE /api/friends"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/friends` 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-72b1fad5c9a5616e", "name": "Unused endpoint: USE /api/voice", "shortDescription": {"text": "Unused endpoint: USE /api/voice"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/voice` 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-e822f954bcd111da", "name": "Unused endpoint: USE /api/wishes", "shortDescription": {"text": "Unused endpoint: USE /api/wishes"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/wishes` 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-8636dd48e48d1da9", "name": "Unused endpoint: USE /api/sessions", "shortDescription": {"text": "Unused endpoint: USE /api/sessions"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/sessions` 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-1bc898b3b7565990", "name": "Unused endpoint: USE /uploads", "shortDescription": {"text": "Unused endpoint: USE /uploads"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /uploads` 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-76ed4d7d83639e22", "name": "Unused endpoint: USE /api/channels/:channelId/messages/:messageId/react", "shortDescription": {"text": "Unused endpoint: USE /api/channels/:channelId/messages/:messageId/react"}, "fullDescription": {"text": "`apps/api/src/index.ts` declares `USE /api/channels/:channelId/messages/:messageId/react` 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-120d320863420a12", "name": "Unused endpoint: POST /route", "shortDescription": {"text": "Unused endpoint: POST /route"}, "fullDescription": {"text": "`apps/api/src/middleware/validate.ts` declares `POST /route` 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-2480239b19c7551f", "name": "Unused endpoint: POST /channels/:channelId/read", "shortDescription": {"text": "Unused endpoint: POST /channels/:channelId/read"}, "fullDescription": {"text": "`apps/api/src/routes/reads.ts` declares `POST /channels/:channelId/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-f370110cf379889a", "name": "Unused endpoint: GET /reads/channels", "shortDescription": {"text": "Unused endpoint: GET /reads/channels"}, "fullDescription": {"text": "`apps/api/src/routes/reads.ts` declares `GET /reads/channels` 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-e1a8d1b0515a637a", "name": "Unused endpoint: POST /dm/:conversationId/read", "shortDescription": {"text": "Unused endpoint: POST /dm/:conversationId/read"}, "fullDescription": {"text": "`apps/api/src/routes/reads.ts` declares `POST /dm/:conversationId/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-252520ed2a765fd1", "name": "Unused endpoint: GET /reads/dm", "shortDescription": {"text": "Unused endpoint: GET /reads/dm"}, "fullDescription": {"text": "`apps/api/src/routes/reads.ts` declares `GET /reads/dm` 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-5baa8971ebe192a1", "name": "Unused endpoint: GET /", "shortDescription": {"text": "Unused endpoint: GET /"}, "fullDescription": {"text": "`apps/api/src/routes/discover.ts` 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-526c88d602744f9f", "name": "Unused endpoint: POST /:serverId/join", "shortDescription": {"text": "Unused endpoint: POST /:serverId/join"}, "fullDescription": {"text": "`apps/api/src/routes/discover.ts` declares `POST /:serverId/join` 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-304b6f2b403d93f7", "name": "Unused endpoint: POST /register", "shortDescription": {"text": "Unused endpoint: POST /register"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `POST /register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `POST /login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7ce17d6b092a81ca", "name": "Unused endpoint: POST /refresh", "shortDescription": {"text": "Unused endpoint: POST /refresh"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `POST /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-99fc36db98c134ce", "name": "Unused endpoint: POST /logout", "shortDescription": {"text": "Unused endpoint: POST /logout"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `POST /logout` 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-fd1dc91abf32142d", "name": "Unused endpoint: GET /me", "shortDescription": {"text": "Unused endpoint: GET /me"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `GET /me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dbab2d3762ba5ff0", "name": "Unused endpoint: POST /password", "shortDescription": {"text": "Unused endpoint: POST /password"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `POST /password` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fc887069ed46c09c", "name": "Unused endpoint: POST /onboarded", "shortDescription": {"text": "Unused endpoint: POST /onboarded"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `POST /onboarded` 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-5c5d06c999404370", "name": "Unused endpoint: GET /google", "shortDescription": {"text": "Unused endpoint: GET /google"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `GET /google` 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-424854ab10436e86", "name": "Unused endpoint: GET /google/callback", "shortDescription": {"text": "Unused endpoint: GET /google/callback"}, "fullDescription": {"text": "`apps/api/src/routes/auth.ts` declares `GET /google/callback` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3bdeef6f4c0e78b5", "name": "Unused endpoint: GET /:userId/badges", "shortDescription": {"text": "Unused endpoint: GET /:userId/badges"}, "fullDescription": {"text": "`apps/api/src/routes/badges.ts` declares `GET /:userId/badges` 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-71db42b35ae52eb4", "name": "Unused endpoint: GET /:serverId/badges", "shortDescription": {"text": "Unused endpoint: GET /:serverId/badges"}, "fullDescription": {"text": "`apps/api/src/routes/badges.ts` declares `GET /:serverId/badges` 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-10245e94836c0fbe", "name": "Unused endpoint: POST /:serverId/badges", "shortDescription": {"text": "Unused endpoint: POST /:serverId/badges"}, "fullDescription": {"text": "`apps/api/src/routes/badges.ts` declares `POST /:serverId/badges` 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-81b10bd1b3fa8956", "name": "Unused endpoint: DELETE /:serverId/badges/:badgeId", "shortDescription": {"text": "Unused endpoint: DELETE /:serverId/badges/:badgeId"}, "fullDescription": {"text": "`apps/api/src/routes/badges.ts` declares `DELETE /:serverId/badges/:badgeId` 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-8891a249770f5550", "name": "Unused endpoint: POST /:serverId/badges/:badgeId/grants", "shortDescription": {"text": "Unused endpoint: POST /:serverId/badges/:badgeId/grants"}, "fullDescription": {"text": "`apps/api/src/routes/badges.ts` declares `POST /:serverId/badges/:badgeId/grants` 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-1a30692a3a980380", "name": "Unused endpoint: DELETE /:serverId/badges/:badgeId/grants/:userId", "shortDescription": {"text": "Unused endpoint: DELETE /:serverId/badges/:badgeId/grants/:userId"}, "fullDescription": {"text": "`apps/api/src/routes/badges.ts` declares `DELETE /:serverId/badges/:badgeId/grants/:userId` 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-d6d412ba6647f6cc", "name": "Unused endpoint: GET /live", "shortDescription": {"text": "Unused endpoint: GET /live"}, "fullDescription": {"text": "`apps/api/src/routes/health.ts` declares `GET /live` 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-2bca43d03db4d010", "name": "Unused endpoint: GET /channels/:channelId/threads", "shortDescription": {"text": "Unused endpoint: GET /channels/:channelId/threads"}, "fullDescription": {"text": "`apps/api/src/routes/threads.ts` declares `GET /channels/:channelId/threads` 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-2e1103bdd8254f22", "name": "Unused endpoint: POST /channels/:channelId/threads", "shortDescription": {"text": "Unused endpoint: POST /channels/:channelId/threads"}, "fullDescription": {"text": "`apps/api/src/routes/threads.ts` declares `POST /channels/:channelId/threads` 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-c0386ebe5c0051fd", "name": "Unused endpoint: GET /threads/:threadId/messages", "shortDescription": {"text": "Unused endpoint: GET /threads/:threadId/messages"}, "fullDescription": {"text": "`apps/api/src/routes/threads.ts` declares `GET /threads/:threadId/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}}]}}, "automationDetails": {"id": "repobility/23064"}, "properties": {"repository": "Xryonz/Umbra", "repoUrl": "https://github.com/Xryonz/Umbra", "branch": "main"}, "results": [{"ruleId": "scanner-8c45cb565fc20606", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/fcm.ts:33"}, "properties": {"repobilityId": "bac6998782641380", "scanner": "scanner-primary", "fingerprint": "8c45cb565fc20606", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a8a26f7ab3371296", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/push.ts:18"}, "properties": {"repobilityId": "b334247acbc300cb", "scanner": "scanner-primary", "fingerprint": "a8a26f7ab3371296", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-78301bdc5deb84e3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/lib/redis.ts:17"}, "properties": {"repobilityId": "98446690a966060d", "scanner": "scanner-primary", "fingerprint": "78301bdc5deb84e3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ec5fa7a11f2d6c58", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/db/migrate.ts:22"}, "properties": {"repobilityId": "4c947c823da5fa9d", "scanner": "scanner-primary", "fingerprint": "ec5fa7a11f2d6c58", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f7b6280fd4074fa8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/db/manualMigrate.ts:214"}, "properties": {"repobilityId": "f9407f02ed3d4566", "scanner": "scanner-primary", "fingerprint": "f7b6280fd4074fa8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1325d6e696765809", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/web/vite.config.ts:29"}, "properties": {"repobilityId": "db63813fb5db03e9", "scanner": "scanner-primary", "fingerprint": "1325d6e696765809", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-28314033bf55c840", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/CommandPalette.tsx:108"}, "properties": {"repobilityId": "6397c6bea18e8bb0", "scanner": "scanner-primary", "fingerprint": "28314033bf55c840", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d43dffd620225069", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/Lightbox.tsx:60"}, "properties": {"repobilityId": "020abfd90b9fd1f2", "scanner": "scanner-primary", "fingerprint": "d43dffd620225069", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-13aa1994de55c3db", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/AppearanceSection.tsx:87"}, "properties": {"repobilityId": "5c77cf48b34fb0b8", "scanner": "scanner-primary", "fingerprint": "13aa1994de55c3db", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cd1060dbc949c500", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/NameColorsSection.tsx:80"}, "properties": {"repobilityId": "998b14f2c8ad6556", "scanner": "scanner-primary", "fingerprint": "cd1060dbc949c500", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-726bc5cc38f3e437", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/settings/sections/WishingStarSection.tsx:164"}, "properties": {"repobilityId": "1b780a93018dbda6", "scanner": "scanner-primary", "fingerprint": "726bc5cc38f3e437", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b1519ae041e56c11", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/MobileMoreSheet.tsx:107"}, "properties": {"repobilityId": "43ce2c7e52a23dab", "scanner": "scanner-primary", "fingerprint": "b1519ae041e56c11", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-383b31d8ed6ac9fd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/Sidebar.tsx:418"}, "properties": {"repobilityId": "ba259c597714d104", "scanner": "scanner-primary", "fingerprint": "383b31d8ed6ac9fd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0a651a01c94af825", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/layout/UserFooter.tsx:59"}, "properties": {"repobilityId": "5831e3a67545e3c8", "scanner": "scanner-primary", "fingerprint": "0a651a01c94af825", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ce070100ed3a31a6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/notifications/NotificationBell.tsx:264"}, "properties": {"repobilityId": "34d10e6284e2c187", "scanner": "scanner-primary", "fingerprint": "ce070100ed3a31a6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d0fa42e50b9956c7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/PinnedMessagesSheet.tsx:64"}, "properties": {"repobilityId": "5180d52f8f24d32b", "scanner": "scanner-primary", "fingerprint": "d0fa42e50b9956c7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-52bc505e58571a07", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/RecordingDisplay.tsx:47"}, "properties": {"repobilityId": "7d99dedebe747c26", "scanner": "scanner-primary", "fingerprint": "52bc505e58571a07", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cfd06e5e9d2c81e2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageItem.tsx:780"}, "properties": {"repobilityId": "5d7d7cf381cdc27c", "scanner": "scanner-primary", "fingerprint": "cfd06e5e9d2c81e2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e64d3e7fd4a9980c", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/components/chat/CodeBlock.tsx:34"}, "properties": {"repobilityId": "0c84d3f6af7451b2", "scanner": "scanner-primary", "fingerprint": "e64d3e7fd4a9980c", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-640a159c701235ad", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageInput.tsx:456"}, "properties": {"repobilityId": "4bbb27cbfd838f29", "scanner": "scanner-primary", "fingerprint": "640a159c701235ad", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7cf75700b9908dfc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/RightPanel.tsx:68"}, "properties": {"repobilityId": "5a8724d4950c62f7", "scanner": "scanner-primary", "fingerprint": "7cf75700b9908dfc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bfaf96082a38efd6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/MessageMobileActions.tsx:43"}, "properties": {"repobilityId": "4988ff63342e8d23", "scanner": "scanner-primary", "fingerprint": "bfaf96082a38efd6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7fbc753cfe79815c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/PollCard.tsx:143"}, "properties": {"repobilityId": "168f7c9ea637bed2", "scanner": "scanner-primary", "fingerprint": "7fbc753cfe79815c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9eea185b24856d46", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/chat/Message/MessageAttachments.tsx:163"}, "properties": {"repobilityId": "b31937cc17474a38", "scanner": "scanner-primary", "fingerprint": "9eea185b24856d46", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fad0973823045b96", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/VoiceCallPanel.tsx:109"}, "properties": {"repobilityId": "8fd45a486a9ba70b", "scanner": "scanner-primary", "fingerprint": "fad0973823045b96", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1a4377c994186d23", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/IncomingCallModal.tsx:227"}, "properties": {"repobilityId": "3ad19bbc00d8269f", "scanner": "scanner-primary", "fingerprint": "1a4377c994186d23", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-735f4e4347006007", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/voice/VoiceCallStage.tsx:91"}, "properties": {"repobilityId": "24395fcb05c2aba2", "scanner": "scanner-primary", "fingerprint": "735f4e4347006007", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-314513d3fe3b2e03", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/bookmarks/BookmarksSheet.tsx:115"}, "properties": {"repobilityId": "5a187832a7e9969b", "scanner": "scanner-primary", "fingerprint": "314513d3fe3b2e03", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3ae86fba17773a52", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dm/DMChat.tsx:407"}, "properties": {"repobilityId": "0bb0cfe48bc477ec", "scanner": "scanner-primary", "fingerprint": "3ae86fba17773a52", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5db154b63d74119a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/dm/DMInput.tsx:301"}, "properties": {"repobilityId": "35bb12b7dda6467a", "scanner": "scanner-primary", "fingerprint": "5db154b63d74119a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b4806427a66f4afa", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/web/src/lib/socket.ts:78"}, "properties": {"repobilityId": "c1f96c1857f11879", "scanner": "scanner-primary", "fingerprint": "b4806427a66f4afa", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-650bc5d62e1ed675", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 apps/web/src/lib/bioMarkdown.tsx:15"}, "properties": {"repobilityId": "fa9b4283b844878b", "scanner": "scanner-primary", "fingerprint": "650bc5d62e1ed675", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-aa210a94b4737ecc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/FriendsPage.tsx:248"}, "properties": {"repobilityId": "d61bf8150451dc7a", "scanner": "scanner-primary", "fingerprint": "aa210a94b4737ecc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0175830c86041fc9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/AppPage.tsx:148"}, "properties": {"repobilityId": "eb1276a0c1d21ade", "scanner": "scanner-primary", "fingerprint": "0175830c86041fc9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d811eadef2685dbb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/SettingsPage.tsx:176"}, "properties": {"repobilityId": "22ac163bf1d64b7c", "scanner": "scanner-primary", "fingerprint": "d811eadef2685dbb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3f56c41087d804ad", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/DiscoverPage.tsx:89"}, "properties": {"repobilityId": "64b60d9d51ebbc7c", "scanner": "scanner-primary", "fingerprint": "3f56c41087d804ad", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1a2d3923bf5cba68", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/pages/ServerSettingsPage.tsx:226"}, "properties": {"repobilityId": "c78457bd9ff6df9f", "scanner": "scanner-primary", "fingerprint": "1a2d3923bf5cba68", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-26fde097677a2242", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in apps/web/src/components/chat/CodeBlock.tsx:34"}, "properties": {"repobilityId": "6e8459e26d657e21", "scanner": "scanner-primary", "fingerprint": "26fde097677a2242", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/components/chat/CodeBlock.tsx"}, "region": {"startLine": 34}}}]}, {"ruleId": "scanner-05733e84e65ab0e3", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in scripts/predev.mjs:16"}, "properties": {"repobilityId": "a7d913437814906a", "scanner": "scanner-primary", "fingerprint": "05733e84e65ab0e3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/predev.mjs"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-8f554d346d2e7c3c", "level": "note", "message": {"text": "Very large file: apps/web/src/pages/ServerSettingsPage.tsx (1557 lines)"}, "properties": {"repobilityId": "d4a33dab1cf838c9", "scanner": "scanner-primary", "fingerprint": "8f554d346d2e7c3c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "bb655a12170e6d5c", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b06b8d86f24c77f9", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "properties": {"repobilityId": "ce77cd34ed0306d4", "scanner": "scanner-primary", "fingerprint": "b06b8d86f24c77f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-cb3e52667c84fb86", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/types/package.json"}, "properties": {"repobilityId": "b5e2784f829944e6", "scanner": "scanner-primary", "fingerprint": "cb3e52667c84fb86", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/types/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "66ad1378ed46521c", "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": "2c48e1b47a32076f", "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": "5aee3024efec76ca", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "8c4ce1eb0d063146", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "eeb8b97ae84aadb5", "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": "c6782e169ac8cbb2", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-efe11740f28539d9", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/api/src/index.ts:63"}, "properties": {"repobilityId": "f93ad13c66c227b9", "scanner": "scanner-primary", "fingerprint": "efe11740f28539d9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-aef0074efbffe697", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/api/src/config/passport.ts:40"}, "properties": {"repobilityId": "6f4db3dcd24e3811", "scanner": "scanner-primary", "fingerprint": "aef0074efbffe697", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-34c8cb9721bc0a5c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/lib/bot.ts:318"}, "properties": {"repobilityId": "3bcc631676c81c00", "scanner": "scanner-primary", "fingerprint": "34c8cb9721bc0a5c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bc25e97ce44da496", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/api/src/routes/auth.ts:45"}, "properties": {"repobilityId": "fef902c8de11a35d", "scanner": "scanner-primary", "fingerprint": "bc25e97ce44da496", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cd1bfe4a802f269a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 apps/api/src/routes/gif.ts:68"}, "properties": {"repobilityId": "d46c7e2cb492ce55", "scanner": "scanner-primary", "fingerprint": "cd1bfe4a802f269a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-59ff985a9cbbd046", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/components/layout/Sidebar.tsx:226"}, "properties": {"repobilityId": "0416075cde2fae01", "scanner": "scanner-primary", "fingerprint": "59ff985a9cbbd046", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c18e7adbbc112893", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/components/anim/PageTransition.tsx:21"}, "properties": {"repobilityId": "a27f7c7a0c1de08d", "scanner": "scanner-primary", "fingerprint": "c18e7adbbc112893", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-117bd6c6a230d9a7", "level": "none", "message": {"text": "Commented-code block (6 lines) in apps/web/src/components/chat/MessageInput.tsx:91"}, "properties": {"repobilityId": "5055c284694c2044", "scanner": "scanner-primary", "fingerprint": "117bd6c6a230d9a7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1da2bbe851346cbf", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/components/chat/MessageList.tsx:270"}, "properties": {"repobilityId": "6a4eaca8e89e0c14", "scanner": "scanner-primary", "fingerprint": "1da2bbe851346cbf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-02fdcbe9b45b3a48", "level": "none", "message": {"text": "Commented-code block (7 lines) in apps/web/src/lib/api.ts:25"}, "properties": {"repobilityId": "194899b9400cd648", "scanner": "scanner-primary", "fingerprint": "02fdcbe9b45b3a48", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c8575c8e7684dda5", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/hooks/useServerEmojis.tsx:99"}, "properties": {"repobilityId": "bc9a43f4c38935ed", "scanner": "scanner-primary", "fingerprint": "c8575c8e7684dda5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7f41931f64a227fe", "level": "none", "message": {"text": "Commented-code block (15 lines) in apps/web/src/store/voiceStore.ts:361"}, "properties": {"repobilityId": "d953bbd3af660804", "scanner": "scanner-primary", "fingerprint": "7f41931f64a227fe", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cc0f9d8e41b33b0e", "level": "note", "message": {"text": "11 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "c82cd8cd626c3599", "scanner": "scanner-primary", "fingerprint": "cc0f9d8e41b33b0e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-71063a867d727f62", "level": "warning", "message": {"text": "Frontend route `/auth/callback` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "cb04a27cf406c8f4", "scanner": "scanner-primary", "fingerprint": "71063a867d727f62", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c479eee4fb61c1a2", "level": "warning", "message": {"text": "Frontend route `/invite/:code` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "63efc5f0c267d3f6", "scanner": "scanner-primary", "fingerprint": "c479eee4fb61c1a2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a30e97e5b3f0c1a8", "level": "warning", "message": {"text": "Frontend route `/app/*` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "e6c294d6cae7b629", "scanner": "scanner-primary", "fingerprint": "a30e97e5b3f0c1a8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-b99ad893b2a77417", "level": "warning", "message": {"text": "Frontend route `dm/*` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "properties": {"repobilityId": "6d46a4818f5e85dc", "scanner": "scanner-primary", "fingerprint": "b99ad893b2a77417", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-d4c797d608e6b90a", "level": "warning", "message": {"text": "Frontend route `friends` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "properties": {"repobilityId": "ec0756b6cd05d535", "scanner": "scanner-primary", "fingerprint": "d4c797d608e6b90a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-48892b57a8d3b82f", "level": "warning", "message": {"text": "Frontend route `discover` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "properties": {"repobilityId": "6977c1522b901f8e", "scanner": "scanner-primary", "fingerprint": "48892b57a8d3b82f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-27150a20000d4b08", "level": "warning", "message": {"text": "Frontend route `profile` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "properties": {"repobilityId": "20a022746a50a835", "scanner": "scanner-primary", "fingerprint": "27150a20000d4b08", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-71ca81a6210853c8", "level": "warning", "message": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "properties": {"repobilityId": "2a8ec3f942ab7ce2", "scanner": "scanner-primary", "fingerprint": "71ca81a6210853c8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-2d11c0ef2569762f", "level": "warning", "message": {"text": "Frontend route `servers/:serverId/settings` has no Link/navigate to it \u2014 apps/web/src/pages/AppPage.tsx"}, "properties": {"repobilityId": "80d7b3b7b95a13ef", "scanner": "scanner-primary", "fingerprint": "2d11c0ef2569762f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7633ffbbbed1a57a", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (apps/api/src/lib/bot.ts:318)"}, "properties": {"repobilityId": "dc5b2e69cb4a0cde", "scanner": "scanner-primary", "fingerprint": "7633ffbbbed1a57a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7099634488c5d33c", "level": "error", "message": {"text": "Dangling fetch: POST https://api.anthropic.com/v1/messages (apps/api/src/routes/translate.ts:66)"}, "properties": {"repobilityId": "1c27b843fc8ec471", "scanner": "scanner-primary", "fingerprint": "7099634488c5d33c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2eeaf8c5695bbc33", "level": "note", "message": {"text": "Unused endpoint: USE /api/profile"}, "properties": {"repobilityId": "149dbfc2d61fe724", "scanner": "scanner-primary", "fingerprint": "2eeaf8c5695bbc33", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6eb452fbfb454d20", "level": "note", "message": {"text": "Unused endpoint: USE /api/auth"}, "properties": {"repobilityId": "ca90d9959dfedd33", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0377ae0651490bdd", "level": "note", "message": {"text": "Unused endpoint: USE /api/invites"}, "properties": {"repobilityId": "c598efc4d36400cb", "scanner": "scanner-primary", "fingerprint": "0377ae0651490bdd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d320c3433ba04200", "level": "note", "message": {"text": "Unused endpoint: USE /i"}, "properties": {"repobilityId": "ed2e0be786d20db5", "scanner": "scanner-primary", "fingerprint": "d320c3433ba04200", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7cccc4aacb62228c", "level": "note", "message": {"text": "Unused endpoint: USE /api/servers"}, "properties": {"repobilityId": "53110f90aabda076", "scanner": "scanner-primary", "fingerprint": "7cccc4aacb62228c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0791172e5aa72bb9", "level": "note", "message": {"text": "Unused endpoint: USE /api/channels/:channelId/messages"}, "properties": {"repobilityId": "b216ffa082a1fb21", "scanner": "scanner-primary", "fingerprint": "0791172e5aa72bb9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-481619cd579b97df", "level": "note", "message": {"text": "Unused endpoint: USE /api/channels/:channelId/polls"}, "properties": {"repobilityId": "0ed46b9dd2542376", "scanner": "scanner-primary", "fingerprint": "481619cd579b97df", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "282c1d529b9a1d98", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e2486a74a52b0c2b", "level": "note", "message": {"text": "Unused endpoint: USE /api/dm"}, "properties": {"repobilityId": "4427d1225834b781", "scanner": "scanner-primary", "fingerprint": "e2486a74a52b0c2b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a74449cc5d561bad", "level": "note", "message": {"text": "Unused endpoint: USE /api/search"}, "properties": {"repobilityId": "48bfe109e4b69f4b", "scanner": "scanner-primary", "fingerprint": "a74449cc5d561bad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5777abcaa1a80703", "level": "note", "message": {"text": "Unused endpoint: USE /api/discover"}, "properties": {"repobilityId": "fecd2c214198de8f", "scanner": "scanner-primary", "fingerprint": "5777abcaa1a80703", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6f643fbf10ab5803", "level": "note", "message": {"text": "Unused endpoint: USE /api/upload"}, "properties": {"repobilityId": "4e9636aaa20bcdb4", "scanner": "scanner-primary", "fingerprint": "6f643fbf10ab5803", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-538bbf0ab06b039c", "level": "note", "message": {"text": "Unused endpoint: USE /api/push"}, "properties": {"repobilityId": "31666987285c7fab", "scanner": "scanner-primary", "fingerprint": "538bbf0ab06b039c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-de1e931ca2ef126b", "level": "note", "message": {"text": "Unused endpoint: USE /api/gif"}, "properties": {"repobilityId": "ca39718dc12eff17", "scanner": "scanner-primary", "fingerprint": "de1e931ca2ef126b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ff40cb10f7c8519", "level": "note", "message": {"text": "Unused endpoint: USE /api/users"}, "properties": {"repobilityId": "d96b05699306a9cf", "scanner": "scanner-primary", "fingerprint": "4ff40cb10f7c8519", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-188982f150d29369", "level": "note", "message": {"text": "Unused endpoint: USE /api/bookmarks"}, "properties": {"repobilityId": "99136b684cc529cc", "scanner": "scanner-primary", "fingerprint": "188982f150d29369", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7acee280a96329f0", "level": "note", "message": {"text": "Unused endpoint: USE /api/reminders"}, "properties": {"repobilityId": "d5b6fb6e53f69f8b", "scanner": "scanner-primary", "fingerprint": "7acee280a96329f0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b4a376810bee148", "level": "note", "message": {"text": "Unused endpoint: USE /api/translate"}, "properties": {"repobilityId": "74a09a6ed2c309b8", "scanner": "scanner-primary", "fingerprint": "3b4a376810bee148", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7f6413794dcdf522", "level": "note", "message": {"text": "Unused endpoint: USE /api/friends"}, "properties": {"repobilityId": "3cce9cc0822edc8a", "scanner": "scanner-primary", "fingerprint": "7f6413794dcdf522", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-72b1fad5c9a5616e", "level": "note", "message": {"text": "Unused endpoint: USE /api/voice"}, "properties": {"repobilityId": "cf24a00fdb3e9b55", "scanner": "scanner-primary", "fingerprint": "72b1fad5c9a5616e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e822f954bcd111da", "level": "note", "message": {"text": "Unused endpoint: USE /api/wishes"}, "properties": {"repobilityId": "36b098fa1701478f", "scanner": "scanner-primary", "fingerprint": "e822f954bcd111da", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8636dd48e48d1da9", "level": "note", "message": {"text": "Unused endpoint: USE /api/sessions"}, "properties": {"repobilityId": "593fdfdd10f4d03b", "scanner": "scanner-primary", "fingerprint": "8636dd48e48d1da9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1bc898b3b7565990", "level": "note", "message": {"text": "Unused endpoint: USE /uploads"}, "properties": {"repobilityId": "6c06cdb1d30426fb", "scanner": "scanner-primary", "fingerprint": "1bc898b3b7565990", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76ed4d7d83639e22", "level": "note", "message": {"text": "Unused endpoint: USE /api/channels/:channelId/messages/:messageId/react"}, "properties": {"repobilityId": "a1fad48cf8844c1c", "scanner": "scanner-primary", "fingerprint": "76ed4d7d83639e22", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-120d320863420a12", "level": "note", "message": {"text": "Unused endpoint: POST /route"}, "properties": {"repobilityId": "8035feda8b9e9d69", "scanner": "scanner-primary", "fingerprint": "120d320863420a12", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2480239b19c7551f", "level": "note", "message": {"text": "Unused endpoint: POST /channels/:channelId/read"}, "properties": {"repobilityId": "ce683542f393ccc9", "scanner": "scanner-primary", "fingerprint": "2480239b19c7551f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f370110cf379889a", "level": "note", "message": {"text": "Unused endpoint: GET /reads/channels"}, "properties": {"repobilityId": "e0a0294897e02e2b", "scanner": "scanner-primary", "fingerprint": "f370110cf379889a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e1a8d1b0515a637a", "level": "note", "message": {"text": "Unused endpoint: POST /dm/:conversationId/read"}, "properties": {"repobilityId": "ee520c209d690b91", "scanner": "scanner-primary", "fingerprint": "e1a8d1b0515a637a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-252520ed2a765fd1", "level": "note", "message": {"text": "Unused endpoint: GET /reads/dm"}, "properties": {"repobilityId": "1187d2c3c96f035a", "scanner": "scanner-primary", "fingerprint": "252520ed2a765fd1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "9058c6a610063201", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-526c88d602744f9f", "level": "note", "message": {"text": "Unused endpoint: POST /:serverId/join"}, "properties": {"repobilityId": "dd144957aba5fe01", "scanner": "scanner-primary", "fingerprint": "526c88d602744f9f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-304b6f2b403d93f7", "level": "note", "message": {"text": "Unused endpoint: POST /register"}, "properties": {"repobilityId": "5a15e3e757e5c2c3", "scanner": "scanner-primary", "fingerprint": "304b6f2b403d93f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "fc5f131b36853471", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7ce17d6b092a81ca", "level": "note", "message": {"text": "Unused endpoint: POST /refresh"}, "properties": {"repobilityId": "60cddeb7ab5f5618", "scanner": "scanner-primary", "fingerprint": "7ce17d6b092a81ca", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99fc36db98c134ce", "level": "note", "message": {"text": "Unused endpoint: POST /logout"}, "properties": {"repobilityId": "6f84d3d981e4a0d2", "scanner": "scanner-primary", "fingerprint": "99fc36db98c134ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd1dc91abf32142d", "level": "note", "message": {"text": "Unused endpoint: GET /me"}, "properties": {"repobilityId": "49227180a82a7bb4", "scanner": "scanner-primary", "fingerprint": "fd1dc91abf32142d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dbab2d3762ba5ff0", "level": "note", "message": {"text": "Unused endpoint: POST /password"}, "properties": {"repobilityId": "eaeffbc95cc2ebba", "scanner": "scanner-primary", "fingerprint": "dbab2d3762ba5ff0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fc887069ed46c09c", "level": "note", "message": {"text": "Unused endpoint: POST /onboarded"}, "properties": {"repobilityId": "45032719b40143a9", "scanner": "scanner-primary", "fingerprint": "fc887069ed46c09c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5c5d06c999404370", "level": "note", "message": {"text": "Unused endpoint: GET /google"}, "properties": {"repobilityId": "e35d05dced6e58a6", "scanner": "scanner-primary", "fingerprint": "5c5d06c999404370", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-424854ab10436e86", "level": "note", "message": {"text": "Unused endpoint: GET /google/callback"}, "properties": {"repobilityId": "71459b4e8734881c", "scanner": "scanner-primary", "fingerprint": "424854ab10436e86", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3bdeef6f4c0e78b5", "level": "note", "message": {"text": "Unused endpoint: GET /:userId/badges"}, "properties": {"repobilityId": "cebcdd0332e33566", "scanner": "scanner-primary", "fingerprint": "3bdeef6f4c0e78b5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-71db42b35ae52eb4", "level": "note", "message": {"text": "Unused endpoint: GET /:serverId/badges"}, "properties": {"repobilityId": "55a3a50fe7388f59", "scanner": "scanner-primary", "fingerprint": "71db42b35ae52eb4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-10245e94836c0fbe", "level": "note", "message": {"text": "Unused endpoint: POST /:serverId/badges"}, "properties": {"repobilityId": "e8587431259fd27f", "scanner": "scanner-primary", "fingerprint": "10245e94836c0fbe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-81b10bd1b3fa8956", "level": "note", "message": {"text": "Unused endpoint: DELETE /:serverId/badges/:badgeId"}, "properties": {"repobilityId": "ec2de44fc01f9135", "scanner": "scanner-primary", "fingerprint": "81b10bd1b3fa8956", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8891a249770f5550", "level": "note", "message": {"text": "Unused endpoint: POST /:serverId/badges/:badgeId/grants"}, "properties": {"repobilityId": "4c8eb4847295ca8c", "scanner": "scanner-primary", "fingerprint": "8891a249770f5550", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1a30692a3a980380", "level": "note", "message": {"text": "Unused endpoint: DELETE /:serverId/badges/:badgeId/grants/:userId"}, "properties": {"repobilityId": "345504b75522fb9c", "scanner": "scanner-primary", "fingerprint": "1a30692a3a980380", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d6d412ba6647f6cc", "level": "note", "message": {"text": "Unused endpoint: GET /live"}, "properties": {"repobilityId": "1c100d603e74087c", "scanner": "scanner-primary", "fingerprint": "d6d412ba6647f6cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2bca43d03db4d010", "level": "note", "message": {"text": "Unused endpoint: GET /channels/:channelId/threads"}, "properties": {"repobilityId": "fea45f4e263f89c6", "scanner": "scanner-primary", "fingerprint": "2bca43d03db4d010", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2e1103bdd8254f22", "level": "note", "message": {"text": "Unused endpoint: POST /channels/:channelId/threads"}, "properties": {"repobilityId": "da2f32ad4bd25290", "scanner": "scanner-primary", "fingerprint": "2e1103bdd8254f22", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c0386ebe5c0051fd", "level": "note", "message": {"text": "Unused endpoint: GET /threads/:threadId/messages"}, "properties": {"repobilityId": "2d11b791fcbd0c6d", "scanner": "scanner-primary", "fingerprint": "c0386ebe5c0051fd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}