{"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-1fb28f0eddc4c581", "name": "Stray `console.log` in TS/JS \u2014 scripts/patch-ffmpeg.js:58", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/patch-ffmpeg.js:58"}, "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-e8961c984efb1687", "name": "Stray `console.log` in TS/JS \u2014 scripts/patch-slsk.js:50", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/patch-slsk.js:50"}, "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-66bc36b022e112f9", "name": "TODO/FIXME marker in shipping code \u2014 webapp/src/zen.js:772", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 webapp/src/zen.js:772"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-10cedf3abe859dac", "name": "Stray `console.log` in TS/JS \u2014 webapp/src/zen.js:879", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/zen.js:879"}, "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-075a77423522721f", "name": "Stray `console.log` in TS/JS \u2014 webapp/src/pwa.ts:6", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/pwa.ts:6"}, "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-5f13db6d0cb0b556", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/RelatedTracks.tsx:73", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/RelatedTracks.tsx:73"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d7d4b023cea6a226", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/MetadataMatchModal.tsx:163", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/MetadataMatchModal.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-c2907a7c433879ef", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/layout/Sidebar.tsx:297", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/layout/Sidebar.tsx:297"}, "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-3da152327ac6b4d9", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/player/QueuePanel.tsx:36", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/player/QueuePanel.tsx:36"}, "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-3e15e1ade9beff1b", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/player/PlayerBar.tsx:422", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/player/PlayerBar.tsx:422"}, "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-5a6cb986114693c7", "name": "Stray `console.log` in TS/JS \u2014 webapp/src/components/player/PlayerBar.tsx:225", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/components/player/PlayerBar.tsx:225"}, "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-7291e357bdb74b94", "name": "Stray `console.log` in TS/JS \u2014 webapp/src/components/modals/CheckoutModal.tsx:76", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/components/modals/CheckoutModal.tsx:76"}, "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-c403a1f63d8f76e2", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminAssetModal.tsx:144", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminAssetModal.tsx:144"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4e210a17744bdd81", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminTrackModal.tsx:227", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminTrackModal.tsx:227"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3d975e0ca198839d", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AdminTrackModal.tsx:273", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AdminTrackModal.tsx:273"}, "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-125e203f65923a45", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/SubscriptionModal.tsx:117", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/SubscriptionModal.tsx:117"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f03acc9104c73079", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/SubscriptionModal.tsx:165", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/SubscriptionModal.tsx:165"}, "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-74e2aa555fa288d0", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UnlockModal.tsx:60", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UnlockModal.tsx:60"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7fad8e03b03a740a", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UploadTracksModal.tsx:202", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UploadTracksModal.tsx:202"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bd5f1bae64a93d73", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/UploadTracksModal.tsx:307", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/UploadTracksModal.tsx:307"}, "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-0973e01ad3c4f1a4", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminArtistModal.tsx:257", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminArtistModal.tsx:257"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b0785e3b29fa31bd", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AdminArtistModal.tsx:331", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AdminArtistModal.tsx:331"}, "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-b272e1212329d033", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UnlockCodeManager.tsx:61", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UnlockCodeManager.tsx:61"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3cd9811d290ac961", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/BatchTrackEditModal.tsx:146", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/BatchTrackEditModal.tsx:146"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-30b456f220ac6955", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/PlaylistModal.tsx:107", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/PlaylistModal.tsx:107"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-05ac040a757df8b4", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/PlaylistModal.tsx:145", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/PlaylistModal.tsx:145"}, "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-71a97be7fd882417", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/ArtistMetadataPickerModal.tsx:111", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/ArtistMetadataPickerModal.tsx:111"}, "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-319805c24249ccfd", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AddBandcampTrackModal.tsx:129", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AddBandcampTrackModal.tsx:129"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f40bd11a7cd77020", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AddTrackToUserPlaylistModal.tsx:184", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AddTrackToUserPlaylistModal.tsx:184"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0b6409ccee1aa5cb", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AddTrackToUserPlaylistModal.tsx:265", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AddTrackToUserPlaylistModal.tsx:265"}, "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-38ee198891abcc6b", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminReleaseModal.tsx:197", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminReleaseModal.tsx:197"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-120d1e6a888cf729", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/ArtistKeysModal.tsx:50", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/ArtistKeysModal.tsx:50"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f7ee16e1c13d2f3f", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/CreatePostModal.tsx:117", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/CreatePostModal.tsx:117"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5636045af50ef09f", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/components/modals/CreatePostModal.tsx:218", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/components/modals/CreatePostModal.tsx:218"}, "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-0fff5a455bf482b2", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminUserModal.tsx:131", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminUserModal.tsx:131"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-24cf64b73848cc4f", "name": "Icon-only button without accessible name \u2014 webapp/src/components/modals/CreateUserPlaylistModal.tsx:65", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/CreateUserPlaylistModal.tsx:65"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f8c4e51b46cd9d18", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/ui/PageHeader.tsx:39", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/ui/PageHeader.tsx:39"}, "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-e5d6857ccded121e", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/artist/ArtistFediversePanel.tsx:509", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/artist/ArtistFediversePanel.tsx:509"}, "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-0ef10887d26e723c", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/components/artist/ArtistFediversePanel.tsx:758", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/components/artist/ArtistFediversePanel.tsx:758"}, "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-343ab5db5cf3ebca", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/IntegrationsPanel.tsx:514", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/IntegrationsPanel.tsx:514"}, "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-4fc5a6b99b50a39e", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/StoragePanel.tsx:140", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/StoragePanel.tsx:140"}, "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-50924fe691da527f", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/AdminSettingsPanel.tsx:554", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/AdminSettingsPanel.tsx:554"}, "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-47fad3e464dc429e", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/AdminFederationPanel.tsx:247", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/AdminFederationPanel.tsx:247"}, "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-b26f32a0c137dd81", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/AdminReleaseEditor.tsx:609", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/AdminReleaseEditor.tsx:609"}, "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-95a4ed4ee38cf722", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Network.tsx:269", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Network.tsx:269"}, "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-b57bb612b9a76483", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/Network.tsx:182", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/Network.tsx:182"}, "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-b1a1ef0952b9e23a", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/Post.tsx:148", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/Post.tsx:148"}, "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-67e220ab21aa17b1", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Dig.tsx:163", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Dig.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-e59f0d1f974a804b", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Favorites.tsx:256", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Favorites.tsx:256"}, "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-7fefa35ca92ba7a1", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Tracks.tsx:160", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Tracks.tsx:160"}, "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-84cc2789e8034b4d", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Artists.tsx:215", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Artists.tsx:215"}, "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-954994639feb0bb3", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Stats.tsx:63", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Stats.tsx:63"}, "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-8e40771246763263", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Playlists.tsx:214", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Playlists.tsx:214"}, "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-265728890b515a37", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Board.tsx:474", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Board.tsx:474"}, "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-13248c926ca7a100", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/ArtistDetails.tsx:352", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/ArtistDetails.tsx:352"}, "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-5b1bcb0db22829c7", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/ArtistDetails.tsx:284", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/ArtistDetails.tsx:284"}, "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-b400bbe73ef99c4b", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/AlbumDetails.tsx:331", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/AlbumDetails.tsx:331"}, "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-06bf97525722b2dd", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Search.tsx:287", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Search.tsx:287"}, "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-5e2e7272baff4a68", "name": "Icon-only button without accessible name \u2014 webapp/src/pages/Store.tsx:49", "shortDescription": {"text": "Icon-only button without accessible name \u2014 webapp/src/pages/Store.tsx:49"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3710f995bb38c096", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Store.tsx:81", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Store.tsx:81"}, "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-25fca779ce4ef26e", "name": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/ContentSearch.tsx:418", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/ContentSearch.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-5593c5b50f10fd3b", "name": "Stray `console.log` in TS/JS \u2014 webapp/src/pages/ContentSearch.tsx:270", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/pages/ContentSearch.tsx:270"}, "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-cbb69c627fd6a26e", "name": "Stray `console.log` in TS/JS \u2014 webapp/src/hooks/useOwnedNFTs.ts:69", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/hooks/useOwnedNFTs.ts:69"}, "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-228e7d4757f878b1", "name": "TODO/FIXME marker in shipping code \u2014 deps/zen/index.js:443", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 deps/zen/index.js:443"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e3707de6273a60f7", "name": "Stray `console.log` in TS/JS \u2014 deps/zen/index.js:591", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 deps/zen/index.js:591"}, "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-fb48a0b7d38e5c6d", "name": "Stray `console.log` in TS/JS \u2014 src/index.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/index.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-21ed23401a4c750d", "name": "Stray `console.log` in TS/JS \u2014 src/instrument.ts:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/instrument.ts:26"}, "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-c0dfc2b6b5a6cff4", "name": "Stray `console.log` in TS/JS \u2014 src/server/server.ts:130", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/server.ts:130"}, "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-47da7590f68b4fbd", "name": "Stray `console.log` in TS/JS \u2014 src/server/__tests__/orphan-fix.test.ts:95", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/__tests__/orphan-fix.test.ts:95"}, "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-3af3feb89ad19a8f", "name": "Stray `console.log` in TS/JS \u2014 src/server/providers/download/torrent.provider.ts:63", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/providers/download/torrent.provider.ts:63"}, "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-770a37119966315d", "name": "Stray `console.log` in TS/JS \u2014 src/server/providers/streaming/soundcloud.provider.ts:73", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/providers/streaming/soundcloud.provider.ts:73"}, "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-dadbf4c95e8749ec", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/storage.ts:61", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/storage.ts:61"}, "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-8566500851510dbc", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/upload.ts:26", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/upload.ts:26"}, "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-85abc76562d365a3", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/releases.ts:179", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/releases.ts:179"}, "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-4cf260851fa12ce7", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/artists.ts:458", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/artists.ts:458"}, "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-47347e7eda629faf", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/__tests__/upload_security.test.ts:97", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/__tests__/upload_security.test.ts:97"}, "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-c274cb3684d93c93", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/auth/users.ts:82", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/auth/users.ts:82"}, "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-394ff8d83cac9a68", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/api/chat.ts:87", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/api/chat.ts:87"}, "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-04297d02fc6a1619", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/api/payments.ts:219", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/api/payments.ts:219"}, "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-d73eb5daba60a440", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/search.ts:101", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/search.ts:101"}, "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-024ac2fef4afe781", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/activitypub.ts:37", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/activitypub.ts:37"}, "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-568fc0c99059c04e", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/proxy.ts:40", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/proxy.ts:40"}, "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-daf33a9f7810b9b9", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/__tests__/activitypub.bench.test.ts:110", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/__tests__/activitypub.bench.test.ts:110"}, "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-5e6a0a28622e3a08", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/backup.ts:52", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/backup.ts:52"}, "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-64ce4ab628b3f7d7", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/browser.ts:188", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/browser.ts:188"}, "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-e1ec40c8b9f1df1c", "name": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/admin.ts:446", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/admin.ts:446"}, "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-71cdef6843e04e3e", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/soulseek.ts:69", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/soulseek.ts:69"}, "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-8ca14757d19cf7c2", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/telegram-bot.ts:214", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/telegram-bot.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-de9c966eecf6a705", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/torrent.service.ts:54", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/torrent.service.ts:54"}, "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-d4cb20e9ed45c81f", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/live/hls.service.ts:81", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/live/hls.service.ts:81"}, "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-5f2f7b91b21492a1", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/auth/auth.service.ts:14", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/auth/auth.service.ts:14"}, "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-e1343ce6fc596802", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/media/ffmpeg.ts:52", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/media/ffmpeg.ts:52"}, "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-6d25d6eef0b0ac2e", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/media/media-engine.ts:484", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/media/media-engine.ts:484"}, "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-a74ebcc3a98164ae", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/network/federated-discovery.service.ts:257", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/network/federated-discovery.service.ts:257"}, "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-0a18186e4d8bdd6f", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/network/rss.service.ts:106", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/network/rss.service.ts:106"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-094ce12184677589", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/catalog.service.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/catalog.service.ts:36"}, "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-ff080526b4ca45e6", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/price.ts:52", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/price.ts:52"}, "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-44230d3574f155b3", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/localization.service.ts:58", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/localization.service.ts:58"}, "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-b10d32d878a6c32e", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/scanner.service.ts:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/scanner.service.ts:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-573db286ecd11453", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/library-sync.ts:86", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/library-sync.ts:86"}, "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-270f33753fd5c101", "name": "TODO/FIXME marker in shipping code \u2014 src/server/modules/catalog/lifecycle.service.ts:150", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/server/modules/catalog/lifecycle.service.ts:150"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b7bcb913c7ff3fba", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/lifecycle.service.ts:37", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/lifecycle.service.ts:37"}, "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-c2713ed0aa396898", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/scanner.ts:251", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/scanner.ts:251"}, "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-9a0dac18b5851d74", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/maintenance.service.ts:29", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/maintenance.service.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-a7d3b787084f2a32", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/download.service.ts:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/download.service.ts:32"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f352d394568d52e3", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/maintenance.startup.ts:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/maintenance.startup.ts:35"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ca66b6b3c734186", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/autotagger.service.ts:62", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/autotagger.service.ts:62"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8581bb5664598b45", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/fedify/fedify.ts:358", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/fedify/fedify.ts:358"}, "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-0547b155a014c393", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/workers/task-manager.ts:59", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/workers/task-manager.ts:59"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e93427cd19bff8e1", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/publishing/publishing.service.ts:50", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/publishing/publishing.service.ts:50"}, "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-4e985661bbde8b24", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.service.ts:96", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.service.ts:96"}, "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-6eeca4d6ff01536a", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.transport.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.transport.ts:36"}, "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-8582167fda5d3d03", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.delivery-queue.ts:77", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.delivery-queue.ts:77"}, "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-caacb61ce72a385e", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/scrobble/scrobble.service.ts:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/scrobble/scrobble.service.ts:24"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6faa6f916bf2854c", "name": "Stray `console.log` in TS/JS \u2014 src/server/modules/streaming/streaming.service.ts:67", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/streaming/streaming.service.ts:67"}, "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-0e06fa40130069c3", "name": "Stray `console.log` in TS/JS \u2014 src/server/repositories/artist.repository.ts:72", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/repositories/artist.repository.ts:72"}, "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-78c25cc6cfce369e", "name": "Stray `console.log` in TS/JS \u2014 src/server/core/config.ts:73", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/config.ts:73"}, "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-6b3d5d516c09a8f1", "name": "Stray `console.log` in TS/JS \u2014 src/server/core/provider.ts:34", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/provider.ts:34"}, "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-d36245b45370c7af", "name": "Stray `console.log` in TS/JS \u2014 src/server/core/plugin-loader.ts:42", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/plugin-loader.ts:42"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bd21fe002d9aba9b", "name": "Stray `console.log` in TS/JS \u2014 src/server/core/database.ts:52", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/database.ts:52"}, "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-ef92df3cf6791238", "name": "Stray `console.log` in TS/JS \u2014 src/server/core/managers/social.ts:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/managers/social.ts:23"}, "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-036f591d7fe0f2ca", "name": "Stray `console.log` in TS/JS \u2014 src/tools/migrate-dedupe.ts:38", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/migrate-dedupe.ts:38"}, "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-ad040eec09a66121", "name": "Stray `console.log` in TS/JS \u2014 src/tools/relink-tracks.ts:32", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/relink-tracks.ts:32"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9c7e6e4332b34a02", "name": "Stray `console.log` in TS/JS \u2014 src/tools/backup.ts:33", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/backup.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-78778c500a972b0f", "name": "Stray `console.log` in TS/JS \u2014 src/tools/generate-codes.ts:105", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/generate-codes.ts:105"}, "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-821a06991cd3f07c", "name": "Stray `console.log` in TS/JS \u2014 src/tools/migrate-visibility.ts:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/migrate-visibility.ts:28"}, "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-3701f8df6e6c80c8", "name": "Stray `console.log` in TS/JS \u2014 src/tools/restore.ts:18", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/restore.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-d017e65b98706038", "name": "Stray `console.log` in TS/JS \u2014 src/tools/clean-folders.ts:43", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/clean-folders.ts:43"}, "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-006551ed3d732efc", "name": "Stray `console.log` in TS/JS \u2014 src/tools/fix-paths.ts:21", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/fix-paths.ts:21"}, "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-a19990c988526f02", "name": "Stray `console.log` in TS/JS \u2014 plugins/demo-provider.js:53", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 plugins/demo-provider.js:53"}, "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-835eae4c7f17a2f8", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b91ec66944e6fd72", "name": "Insecure pattern 'node_child_process' in package.json:20", "shortDescription": {"text": "Insecure pattern 'node_child_process' in package.json:20"}, "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-cb7405c4677dd1a7", "name": "Insecure pattern 'dangerous_innerhtml' in webapp/src/components/modals/CreatePostModal.tsx:218", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/components/modals/CreatePostModal.tsx:218"}, "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-fb460cf1b155a92c", "name": "Insecure pattern 'dangerous_innerhtml' in webapp/src/components/artist/ArtistFediversePanel.tsx:758", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/components/artist/ArtistFediversePanel.tsx:758"}, "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-cc2b35455149543d", "name": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/Network.tsx:182", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/Network.tsx:182"}, "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-251eaea6ec0823c9", "name": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/Post.tsx:148", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/Post.tsx:148"}, "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-fbb455dd01869b15", "name": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/ArtistDetails.tsx:284", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/ArtistDetails.tsx:284"}, "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-f9cf26fba99b8221", "name": "Insecure pattern 'local_storage_auth_token' in webapp/src/services/api.ts:64", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in webapp/src/services/api.ts:64"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-33ce4224fdabc5c2", "name": "Insecure pattern 'exec_used' in src/server/routes/admin/backup.ts:76", "shortDescription": {"text": "Insecure pattern 'exec_used' in src/server/routes/admin/backup.ts:76"}, "fullDescription": {"text": "Found a known-risky pattern (exec_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-bb196a6aced49c43", "name": "Insecure pattern 'node_child_process' in src/server/modules/live/hls.service.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in src/server/modules/live/hls.service.ts:1"}, "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-056df237fc8a9fd3", "name": "Insecure pattern 'node_child_process' in src/server/modules/catalog/localization.service.ts:3", "shortDescription": {"text": "Insecure pattern 'node_child_process' in src/server/modules/catalog/localization.service.ts:3"}, "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-f5c6e806454f7092", "name": "Install-time lifecycle script performs network/shell-sensitive actions", "shortDescription": {"text": "Install-time lifecycle script performs network/shell-sensitive actions"}, "fullDescription": {"text": "preinstall/install/postinstall/prepare scripts execute during dependency installation. Review them carefully for network calls, obfuscation, shell execution, or credential access."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cac75a3d19a4216f", "name": "Very large file: webapp/src/zen.js (8441 lines)", "shortDescription": {"text": "Very large file: webapp/src/zen.js (8441 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-0299d22352dcdb2d", "name": "Very large file: webapp/src/components/artist/ArtistFediversePanel.tsx (1290 lines)", "shortDescription": {"text": "Very large file: webapp/src/components/artist/ArtistFediversePanel.tsx (1290 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-06f583af72fc35c2", "name": "Very large file: webapp/src/pages/AdminReleaseEditor.tsx (1470 lines)", "shortDescription": {"text": "Very large file: webapp/src/pages/AdminReleaseEditor.tsx (1470 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-74f6cc3aa033cc46", "name": "Very large file: webapp/src/pages/Profile.tsx (1509 lines)", "shortDescription": {"text": "Very large file: webapp/src/pages/Profile.tsx (1509 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-b208aa87e38cf32e", "name": "Very large file: webapp/src/pages/ContentSearch.tsx (967 lines)", "shortDescription": {"text": "Very large file: webapp/src/pages/ContentSearch.tsx (967 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-087e55ff98931e77", "name": "Very large file: deps/zen/index.js (5134 lines)", "shortDescription": {"text": "Very large file: deps/zen/index.js (5134 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-f127319e12ba1990", "name": "Very large file: src/server/routes/api/payments.ts (1058 lines)", "shortDescription": {"text": "Very large file: src/server/routes/api/payments.ts (1058 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-06bc0257f6397024", "name": "Very large file: src/server/routes/admin/admin.ts (2206 lines)", "shortDescription": {"text": "Very large file: src/server/routes/admin/admin.ts (2206 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-84c921a8ac3e84cc", "name": "Very large file: src/server/modules/activitypub/activitypub.service.ts (1928 lines)", "shortDescription": {"text": "Very large file: src/server/modules/activitypub/activitypub.service.ts (1928 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-ad76a0f04715c0d4", "name": "Very large file: src/server/core/database.ts (1118 lines)", "shortDescription": {"text": "Very large file: src/server/core/database.ts (1118 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-46191edd49d0d209", "name": "236 TODO/FIXME markers", "shortDescription": {"text": "236 TODO/FIXME markers"}, "fullDescription": {"text": "High count of TODO/FIXME/HACK markers \u2014 track them as issues so they're not forgotten."}, "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 592 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 136 placeholder/mock markers across 48 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-b347463739865ff5", "name": "Agent authority lacks a verifier contract: agents/tc-adoption-ux/SKILL.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: agents/tc-adoption-ux/SKILL.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b96fd5a3219e07ee", "name": "Commented-code block (8 lines) in scripts/patch-slsk.js:8", "shortDescription": {"text": "Commented-code block (8 lines) in scripts/patch-slsk.js:8"}, "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-e8ee64ee0a376d8b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/public/sw.js:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/public/sw.js:35"}, "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-9e80695b2cfb341c", "name": "Commented-code block (7 lines) in webapp/src/zen.js:1130", "shortDescription": {"text": "Commented-code block (7 lines) in webapp/src/zen.js:1130"}, "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-7c91e7903c483264", "name": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/src/zen.js:1369", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/src/zen.js:1369"}, "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-cac8bd5b5c289111", "name": "Commented-code block (6 lines) in webapp/src/stores/useConfigStore.ts:35", "shortDescription": {"text": "Commented-code block (6 lines) in webapp/src/stores/useConfigStore.ts:35"}, "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-e26a908d8e756908", "name": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/src/components/modals/CheckoutModal.tsx:52", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/src/components/modals/CheckoutModal.tsx:52"}, "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-f3aaae8bbed260fd", "name": "Commented-code block (7 lines) in deps/zen/index.js:708", "shortDescription": {"text": "Commented-code block (7 lines) in deps/zen/index.js:708"}, "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-bd2ad3bc7dd415aa", "name": "`fetch()` without try/.catch or AbortSignal \u2014 deps/zen/index.js:2114", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 deps/zen/index.js:2114"}, "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-21fe00ab18cb066c", "name": "Commented-code block (5 lines) in src/utils/networkUtils.test.ts:17", "shortDescription": {"text": "Commented-code block (5 lines) in src/utils/networkUtils.test.ts:17"}, "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-774b00004ba4cbf0", "name": "Commented-code block (5 lines) in src/server/server.ts:173", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/server.ts:173"}, "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-fc53c3a36c710402", "name": "Commented-code block (6 lines) in src/server/__tests__/rateLimit.integration.test.ts:90", "shortDescription": {"text": "Commented-code block (6 lines) in src/server/__tests__/rateLimit.integration.test.ts:90"}, "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-80c5c72bb27ab6d5", "name": "Commented-code block (7 lines) in src/server/__tests__/error-handling.test.ts:6", "shortDescription": {"text": "Commented-code block (7 lines) in src/server/__tests__/error-handling.test.ts:6"}, "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-0ef346f54bd9e7d4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/common/network.ts:29", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/common/network.ts:29"}, "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-0d381989fbd27b44", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/utils/deezer.ts:8", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/utils/deezer.ts:8"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a448c52e9fa89d16", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/utils/spotify.ts:118", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/utils/spotify.ts:118"}, "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-93343c135878aacd", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/providers/scrobble/listenbrainz.provider.ts:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/providers/scrobble/listenbrainz.provider.ts:35"}, "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-a13fc5e2edf3de63", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/providers/scrobble/lastfm.provider.ts:55", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/providers/scrobble/lastfm.provider.ts:55"}, "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-42c310d097377ffa", "name": "Commented-code block (6 lines) in src/server/routes/api/payments.ts:205", "shortDescription": {"text": "Commented-code block (6 lines) in src/server/routes/api/payments.ts:205"}, "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-60e8ccf2def44e8a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/routes/admin/metadata.ts:278", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/routes/admin/metadata.ts:278"}, "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-2dbb223a8f9b5f9b", "name": "Legacy-named symbol `normOld` in src/server/routes/admin/browser.ts:184", "shortDescription": {"text": "Legacy-named symbol `normOld` in src/server/routes/admin/browser.ts:184"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2505107453d4be56", "name": "Legacy-named symbol `admin_old` in src/server/modules/auth/auth.service.ts:163", "shortDescription": {"text": "Legacy-named symbol `admin_old` in src/server/modules/auth/auth.service.ts:163"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-76cfb9339759dbbb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/auth/auth.service.ts:680", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/auth/auth.service.ts:680"}, "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-67328e909db9a1aa", "name": "Commented-code block (5 lines) in src/server/modules/media/ffmpeg.ts:69", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/modules/media/ffmpeg.ts:69"}, "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-86954e16d0115f57", "name": "Commented-code block (7 lines) in src/server/modules/media/media-engine.ts:245", "shortDescription": {"text": "Commented-code block (7 lines) in src/server/modules/media/media-engine.ts:245"}, "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-4855f3f1c76b25a6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/network/catalog-cache.service.ts:90", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/network/catalog-cache.service.ts:90"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0dadad9c1359fcd0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/catalog/__tests__/catalog.service.test.ts:3", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/catalog/__tests__/catalog.service.test.ts:3"}, "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-a775485c9cce2a59", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/publishing/publishing.service.ts:137", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/publishing/publishing.service.ts:137"}, "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-505afd252475072b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/activitypub/activitypub.service.ts:1605", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/activitypub/activitypub.service.ts:1605"}, "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-86564ebed9b49b0a", "name": "Commented-code block (5 lines) in src/server/modules/activitypub/activitypub.transport.ts:25", "shortDescription": {"text": "Commented-code block (5 lines) in src/server/modules/activitypub/activitypub.transport.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-9cac7ce15e72817b", "name": "31 env vars used in code but missing from .env.example", "shortDescription": {"text": "31 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `FFMPEG_PATH`, `NODE_ENV`, `SENTRY_ENVIRONMENT`, `SENTRY_TRACES_SAMPLE_RATE`, `SLSK_PASS`, `SLSK_USER`, `SOULSEEK_DOWNLOAD_DIR`, `SOULSEEK_PASSWORD` + 23 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-59bc4afe4629ae62", "name": "Frontend route `/albums/:idOrSlug` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/albums/:idOrSlug` has no Link/navigate to it \u2014 webapp/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-f196fec02eba23a8", "name": "Frontend route `/releases/:idOrSlug` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/releases/:idOrSlug` has no Link/navigate to it \u2014 webapp/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-e2102210c111e0b2", "name": "Frontend route `/artists/:idOrSlug` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/artists/:idOrSlug` has no Link/navigate to it \u2014 webapp/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-49080945f811eec2", "name": "Frontend route `/playlists/:id` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/playlists/:id` has no Link/navigate to it \u2014 webapp/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-ce0228cd20f5e113", "name": "Frontend route `/my-playlists/:id` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/my-playlists/:id` has no Link/navigate to it \u2014 webapp/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-7f25f90c8145e7c3", "name": "Frontend route `/post/:slug` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/post/:slug` has no Link/navigate to it \u2014 webapp/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-3c71ba96f2aa2bc0", "name": "Frontend route `/share/:id` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/share/:id` has no Link/navigate to it \u2014 webapp/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-456bc989f5a7c863", "name": "Frontend route `/admin/release/:id/edit` has no Link/navigate to it \u2014 webapp/src/App.tsx", "shortDescription": {"text": "Frontend route `/admin/release/:id/edit` has no Link/navigate to it \u2014 webapp/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-e8fd072ec8a471e9", "name": "Dangling fetch: GET /api/payments/onramp-config (webapp/src/components/modals/CheckoutModal.tsx:52)", "shortDescription": {"text": "Dangling fetch: GET /api/payments/onramp-config (webapp/src/components/modals/CheckoutModal.tsx:52)"}, "fullDescription": {"text": "`webapp/src/components/modals/CheckoutModal.tsx:52` calls `GET /api/payments/onramp-config` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/onramp-config`\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-2894af9ed3c49a9c", "name": "Dangling fetch: GET /api/payments/rate/USD (webapp/src/components/modals/CheckoutModal.tsx:101)", "shortDescription": {"text": "Dangling fetch: GET /api/payments/rate/USD (webapp/src/components/modals/CheckoutModal.tsx:101)"}, "fullDescription": {"text": "`webapp/src/components/modals/CheckoutModal.tsx:101` calls `GET /api/payments/rate/USD` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/rate/usd`\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-400a6cb2887cc5fa", "name": "Dangling fetch: POST /api/payments/stripe/create-session (webapp/src/components/modals/CheckoutModal.tsx:153)", "shortDescription": {"text": "Dangling fetch: POST /api/payments/stripe/create-session (webapp/src/components/modals/CheckoutModal.tsx:153)"}, "fullDescription": {"text": "`webapp/src/components/modals/CheckoutModal.tsx:153` calls `POST /api/payments/stripe/create-session` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/stripe/create-session`\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-776998768a5e5374", "name": "Dangling fetch: POST /api/payments/verify (webapp/src/components/modals/CheckoutModal.tsx:325)", "shortDescription": {"text": "Dangling fetch: POST /api/payments/verify (webapp/src/components/modals/CheckoutModal.tsx:325)"}, "fullDescription": {"text": "`webapp/src/components/modals/CheckoutModal.tsx:325` calls `POST /api/payments/verify` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/verify`\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-2167ed4b9b80c5e8", "name": "Dangling fetch: GET /api/payments/rate/USD (webapp/src/components/modals/SubscriptionModal.tsx:51)", "shortDescription": {"text": "Dangling fetch: GET /api/payments/rate/USD (webapp/src/components/modals/SubscriptionModal.tsx:51)"}, "fullDescription": {"text": "`webapp/src/components/modals/SubscriptionModal.tsx:51` calls `GET /api/payments/rate/USD` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/rate/usd`\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-d3639de456ec5df5", "name": "Dangling fetch: GET /api/payments/onramp-config (webapp/src/pages/AdminReleaseEditor.tsx:179)", "shortDescription": {"text": "Dangling fetch: GET /api/payments/onramp-config (webapp/src/pages/AdminReleaseEditor.tsx:179)"}, "fullDescription": {"text": "`webapp/src/pages/AdminReleaseEditor.tsx:179` calls `GET /api/payments/onramp-config` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/onramp-config`\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-090c682b495a098b", "name": "Dangling fetch: GET /api/tracks/${track.id}/lyrics (webapp/src/pages/AdminReleaseEditor.tsx:1213)", "shortDescription": {"text": "Dangling fetch: GET /api/tracks/${track.id}/lyrics (webapp/src/pages/AdminReleaseEditor.tsx:1213)"}, "fullDescription": {"text": "`webapp/src/pages/AdminReleaseEditor.tsx:1213` calls `GET /api/tracks/${track.id}/lyrics` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/tracks/<p>/lyrics`\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-3c286ec4c9f3fb6d", "name": "Dangling fetch: POST /api/payments/verify (webapp/src/hooks/usePurchases.ts:39)", "shortDescription": {"text": "Dangling fetch: POST /api/payments/verify (webapp/src/hooks/usePurchases.ts:39)"}, "fullDescription": {"text": "`webapp/src/hooks/usePurchases.ts:39` calls `POST /api/payments/verify` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/payments/verify`\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-668fdf539669b23f", "name": "Dangling fetch: GET /playlist/${id} (src/server/utils/deezer.ts:14)", "shortDescription": {"text": "Dangling fetch: GET /playlist/${id} (src/server/utils/deezer.ts:14)"}, "fullDescription": {"text": "`src/server/utils/deezer.ts:14` calls `GET /playlist/${id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/playlist/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-982c965ce20af72c", "name": "Dangling fetch: GET /search/track?q=${encodeURIComponent(query)}&limit=${limit} (src/server/utils/deezer.ts:18)", "shortDescription": {"text": "Dangling fetch: GET /search/track?q=${encodeURIComponent(query)}&limit=${limit} (src/server/utils/deezer.ts:18)"}, "fullDescription": {"text": "`src/server/utils/deezer.ts:18` calls `GET /search/track?q=${encodeURIComponent(query)}&limit=${limit}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: helper:request\nNormalized path used for matching: `/search/track`\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-25cc61c9aa0d1768", "name": "Dangling fetch: GET https://itunes.apple.com/search?term=jack+jackson&limit=1 (src/server/routes/admin/admin.ts:1869)", "shortDescription": {"text": "Dangling fetch: GET https://itunes.apple.com/search?term=jack+jackson&limit=1 (src/server/routes/admin/admin.ts:1869)"}, "fullDescription": {"text": "`src/server/routes/admin/admin.ts:1869` calls `GET https://itunes.apple.com/search?term=jack+jackson&limit=1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/itunes.apple.com/search`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-a1164fb3aa0e4440", "name": "Dangling fetch: GET https://musicbrainz.org/ws/2/release/?query=test&fmt=json (src/server/routes/admin/admin.ts:1880)", "shortDescription": {"text": "Dangling fetch: GET https://musicbrainz.org/ws/2/release/?query=test&fmt=json (src/server/routes/admin/admin.ts:1880)"}, "fullDescription": {"text": "`src/server/routes/admin/admin.ts:1880` calls `GET https://musicbrainz.org/ws/2/release/?query=test&fmt=json` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/musicbrainz.org/ws/<p>/release`\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-63dae6a1a2d1a06d", "name": "Dangling fetch: GET https://api.deezer.com/version (src/server/routes/admin/admin.ts:1927)", "shortDescription": {"text": "Dangling fetch: GET https://api.deezer.com/version (src/server/routes/admin/admin.ts:1927)"}, "fullDescription": {"text": "`src/server/routes/admin/admin.ts:1927` calls `GET https://api.deezer.com/version` 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.deezer.com/version`\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-c07af3943aaac09a", "name": "Dangling fetch: HEAD https://open.spotify.com (src/server/routes/admin/admin.ts:1948)", "shortDescription": {"text": "Dangling fetch: HEAD https://open.spotify.com (src/server/routes/admin/admin.ts:1948)"}, "fullDescription": {"text": "`src/server/routes/admin/admin.ts:1948` calls `HEAD https://open.spotify.com` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/open.spotify.com`\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-129067ce0bc37793", "name": "Dangling fetch: HEAD https://soundcloud.com (src/server/routes/admin/admin.ts:1956)", "shortDescription": {"text": "Dangling fetch: HEAD https://soundcloud.com (src/server/routes/admin/admin.ts:1956)"}, "fullDescription": {"text": "`src/server/routes/admin/admin.ts:1956` calls `HEAD https://soundcloud.com` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/soundcloud.com`\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-4be8bc285740e57d", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:53)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:53)"}, "fullDescription": {"text": "`src/server/modules/ai/openrouter.service.ts:53` calls `POST https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\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-7396a186b4e58b28", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:107)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:107)"}, "fullDescription": {"text": "`src/server/modules/ai/openrouter.service.ts:107` calls `POST https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\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-75df8cf996cf6595", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:153)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:153)"}, "fullDescription": {"text": "`src/server/modules/ai/openrouter.service.ts:153` calls `POST https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\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-8e723aa381f71933", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:195)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:195)"}, "fullDescription": {"text": "`src/server/modules/ai/openrouter.service.ts:195` calls `POST https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\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-34ef5bce206cf276", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:243)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:243)"}, "fullDescription": {"text": "`src/server/modules/ai/openrouter.service.ts:243` calls `POST https://openrouter.ai/api/v1/chat/completions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/openrouter.ai/api/v1/chat/completions`\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-1efba9e730cc38d3", "name": "Dangling fetch: GET https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd (src/server/modules/cat", "shortDescription": {"text": "Dangling fetch: GET https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd (src/server/modules/catalog/price.ts:30)"}, "fullDescription": {"text": "`src/server/modules/catalog/price.ts:30` calls `GET https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd` 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.coingecko.com/api/v3/simple/price`\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-55b3e4f90db2f1a7", "name": "Dangling fetch: GET https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD (src/server/modules/catalog/price.ts", "shortDescription": {"text": "Dangling fetch: GET https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD (src/server/modules/catalog/price.ts:47)"}, "fullDescription": {"text": "`src/server/modules/catalog/price.ts:47` calls `GET https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/min-api.cryptocompare.com/data/price`\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-82fb7c0e688aa956", "name": "Dangling fetch: POST https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart (src/server/modules/storage/g", "shortDescription": {"text": "Dangling fetch: POST https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart (src/server/modules/storage/google-drive.service.ts:61)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:61` calls `POST https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/www.googleapis.com/upload/drive/v3/files`\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-15b463815e3790b8", "name": "Dangling fetch: POST https://oauth2.googleapis.com/token (src/server/modules/storage/google-drive.service.ts:72)", "shortDescription": {"text": "Dangling fetch: POST https://oauth2.googleapis.com/token (src/server/modules/storage/google-drive.service.ts:72)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:72` calls `POST https://oauth2.googleapis.com/token` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/oauth2.googleapis.com/token`\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-e51444842bc3cd6e", "name": "Dangling fetch: GET https://www.googleapis.com/oauth2/v2/userinfo (src/server/modules/storage/google-drive.service.ts:83", "shortDescription": {"text": "Dangling fetch: GET https://www.googleapis.com/oauth2/v2/userinfo (src/server/modules/storage/google-drive.service.ts:83)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:83` calls `GET https://www.googleapis.com/oauth2/v2/userinfo` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/www.googleapis.com/oauth2/v2/userinfo`\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-2bf917f783646d54", "name": "Dangling fetch: POST https://oauth2.googleapis.com/token (src/server/modules/storage/google-drive.service.ts:121)", "shortDescription": {"text": "Dangling fetch: POST https://oauth2.googleapis.com/token (src/server/modules/storage/google-drive.service.ts:121)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:121` calls `POST https://oauth2.googleapis.com/token` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/oauth2.googleapis.com/token`\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-eedaf35571c84a59", "name": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files (src/server/modules/storage/google-drive.service.ts:145)", "shortDescription": {"text": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files (src/server/modules/storage/google-drive.service.ts:145)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:145` calls `GET https://www.googleapis.com/drive/v3/files` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/www.googleapis.com/drive/v3/files`\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-07d8f87b71fbeeb5", "name": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files/${fileId} (src/server/modules/storage/google-drive.service", "shortDescription": {"text": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files/${fileId} (src/server/modules/storage/google-drive.service.ts:190)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:190` calls `GET https://www.googleapis.com/drive/v3/files/${fileId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/www.googleapis.com/drive/v3/files/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-008e08b3b1981d05", "name": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files/${fileId} (src/server/modules/storage/google-drive.service", "shortDescription": {"text": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files/${fileId} (src/server/modules/storage/google-drive.service.ts:203)"}, "fullDescription": {"text": "`src/server/modules/storage/google-drive.service.ts:203` calls `GET https://www.googleapis.com/drive/v3/files/${fileId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: axios\nNormalized path used for matching: `/https:/www.googleapis.com/drive/v3/files/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-684f0e83ba7e1558", "name": "Unused endpoint: GET ", "shortDescription": {"text": "Unused endpoint: GET "}, "fullDescription": {"text": "`webapp/src/zen.js` 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-dde3adb27bf7eebe", "name": "Unused endpoint: USE /api", "shortDescription": {"text": "Unused endpoint: USE /api"}, "fullDescription": {"text": "`src/server/server.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-7a30e62ec3c8a210", "name": "Unused endpoint: USE /rest", "shortDescription": {"text": "Unused endpoint: USE /rest"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /rest` 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-a3f49a1ffbf734e7", "name": "Unused endpoint: USE /api/admin/upload", "shortDescription": {"text": "Unused endpoint: USE /api/admin/upload"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin/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-d0ecc923bfaed2b1", "name": "Unused endpoint: USE /api/admin/backup", "shortDescription": {"text": "Unused endpoint: USE /api/admin/backup"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin/backup` 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-54cdeca5d3479794", "name": "Unused endpoint: USE /api/admin/torrents", "shortDescription": {"text": "Unused endpoint: USE /api/admin/torrents"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin/torrents` 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-f8242ba07247d2f8", "name": "Unused endpoint: USE /api/payments", "shortDescription": {"text": "Unused endpoint: USE /api/payments"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/payments` 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-f22cf013c13a7f0c", "name": "Unused endpoint: GET /sw.js", "shortDescription": {"text": "Unused endpoint: GET /sw.js"}, "fullDescription": {"text": "`src/server/server.ts` declares `GET /sw.js` 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-5881fad21d09723d", "name": "Unused endpoint: GET /manifest.json", "shortDescription": {"text": "Unused endpoint: GET /manifest.json"}, "fullDescription": {"text": "`src/server/server.ts` declares `GET /manifest.json` 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-f02a079c69b52f2d", "name": "Unused endpoint: USE /", "shortDescription": {"text": "Unused endpoint: USE /"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /` 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": "`src/server/server.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-d93a530ce10d47d9", "name": "Unused endpoint: USE /api/admin", "shortDescription": {"text": "Unused endpoint: USE /api/admin"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin` 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-ed41dcda9412cd76", "name": "Unused endpoint: USE /api/catalog", "shortDescription": {"text": "Unused endpoint: USE /api/catalog"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/catalog` 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-d54d8e574b4d6eaf", "name": "Unused endpoint: USE /api/artists", "shortDescription": {"text": "Unused endpoint: USE /api/artists"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/artists` 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-c634cbb07d397313", "name": "Unused endpoint: USE /api/albums", "shortDescription": {"text": "Unused endpoint: USE /api/albums"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/albums` 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-7596981f9ee52e11", "name": "Unused endpoint: USE /api/tracks", "shortDescription": {"text": "Unused endpoint: USE /api/tracks"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/tracks` 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-4f40b23feb6761c0", "name": "Unused endpoint: USE /api/dig", "shortDescription": {"text": "Unused endpoint: USE /api/dig"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/dig` 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-927d00be000e74bc", "name": "Unused endpoint: USE /api/playlists", "shortDescription": {"text": "Unused endpoint: USE /api/playlists"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/playlists` 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-d73ccf163920bd14", "name": "Unused endpoint: USE /api/storage", "shortDescription": {"text": "Unused endpoint: USE /api/storage"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/storage` 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-6651c957f9f6894c", "name": "Unused endpoint: USE /api/import", "shortDescription": {"text": "Unused endpoint: USE /api/import"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/import` 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-84e9aca0a013554f", "name": "Unused endpoint: USE /api/releases", "shortDescription": {"text": "Unused endpoint: USE /api/releases"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/releases` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e332c50fd5e64865", "name": "Unused endpoint: USE /api/admin/releases", "shortDescription": {"text": "Unused endpoint: USE /api/admin/releases"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin/releases` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-06c88a2e2dc65557", "name": "Unused endpoint: USE /api/stats", "shortDescription": {"text": "Unused endpoint: USE /api/stats"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e15049a37be53111", "name": "Unused endpoint: USE /api/stats/library", "shortDescription": {"text": "Unused endpoint: USE /api/stats/library"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/stats/library` 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-d0f2ece6e65b9aac", "name": "Unused endpoint: USE /api/community", "shortDescription": {"text": "Unused endpoint: USE /api/community"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/community` 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-bcd27e2f0338f9af", "name": "Unused endpoint: USE /api/browser", "shortDescription": {"text": "Unused endpoint: USE /api/browser"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/browser` 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-0ad0d4a22f4714fc", "name": "Unused endpoint: USE /api/metadata", "shortDescription": {"text": "Unused endpoint: USE /api/metadata"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/metadata` 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": "`src/server/server.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-af74116085195f95", "name": "Unused endpoint: USE /api/comments", "shortDescription": {"text": "Unused endpoint: USE /api/comments"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/comments` 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-2b92dc87a4256298", "name": "Unused endpoint: USE /api/chat", "shortDescription": {"text": "Unused endpoint: USE /api/chat"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/chat` 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-053617d8147f9976", "name": "Unused endpoint: USE /api/live", "shortDescription": {"text": "Unused endpoint: USE /api/live"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/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-034e14696ec45017", "name": "Unused endpoint: USE /api/unlock", "shortDescription": {"text": "Unused endpoint: USE /api/unlock"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/unlock` 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-280808dae6d10af8", "name": "Unused endpoint: USE /api/lifecycle", "shortDescription": {"text": "Unused endpoint: USE /api/lifecycle"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/lifecycle` 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-4264e1f5d1f42db6", "name": "Unused endpoint: USE /api/admin/lifecycle", "shortDescription": {"text": "Unused endpoint: USE /api/admin/lifecycle"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin/lifecycle` 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-686f627db3a6399d", "name": "Unused endpoint: USE /api/ap", "shortDescription": {"text": "Unused endpoint: USE /api/ap"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/ap` 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-b9ed50f6493a17dd", "name": "Unused endpoint: USE /api/proxy", "shortDescription": {"text": "Unused endpoint: USE /api/proxy"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/proxy` 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-be6dd02442a453ee", "name": "Unused endpoint: USE /api/admin/tasks", "shortDescription": {"text": "Unused endpoint: USE /api/admin/tasks"}, "fullDescription": {"text": "`src/server/server.ts` declares `USE /api/admin/tasks` 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": "`src/server/server.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-6b86b877fdc57c6f", "name": "Unused endpoint: GET /share/:id", "shortDescription": {"text": "Unused endpoint: GET /share/:id"}, "fullDescription": {"text": "`src/server/server.ts` declares `GET /share/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3f08df1c2c3eef64", "name": "Unused endpoint: POST /submit-listens", "shortDescription": {"text": "Unused endpoint: POST /submit-listens"}, "fullDescription": {"text": "`src/server/providers/scrobble/listenbrainz.provider.ts` declares `POST /submit-listens` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-512ccb0fd0b230ba", "name": "Unused endpoint: GET /settings", "shortDescription": {"text": "Unused endpoint: GET /settings"}, "fullDescription": {"text": "`src/server/routes/library/catalog.ts` declares `GET /settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e9fcb61155d56f2f", "name": "Unused endpoint: GET /genres", "shortDescription": {"text": "Unused endpoint: GET /genres"}, "fullDescription": {"text": "`src/server/routes/library/catalog.ts` declares `GET /genres` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d16e4fa529c520e9", "name": "Unused endpoint: GET /search", "shortDescription": {"text": "Unused endpoint: GET /search"}, "fullDescription": {"text": "`src/server/routes/library/catalog.ts` declares `GET /search` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0cf9438c240e8830", "name": "Unused endpoint: GET /recommendations/:id", "shortDescription": {"text": "Unused endpoint: GET /recommendations/:id"}, "fullDescription": {"text": "`src/server/routes/library/catalog.ts` declares `GET /recommendations/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e8b3ede8a71f9528", "name": "Unused endpoint: GET /tracks/:id/related", "shortDescription": {"text": "Unused endpoint: GET /tracks/:id/related"}, "fullDescription": {"text": "`src/server/routes/library/catalog.ts` declares `GET /tracks/:id/related` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-314ed0887376003a", "name": "Unused endpoint: GET /random", "shortDescription": {"text": "Unused endpoint: GET /random"}, "fullDescription": {"text": "`src/server/routes/library/catalog.ts` declares `GET /random` 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": "`src/server/routes/library/tracks.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-8e7cd423e638f78f", "name": "Unused endpoint: GET /starred", "shortDescription": {"text": "Unused endpoint: GET /starred"}, "fullDescription": {"text": "`src/server/routes/library/tracks.ts` declares `GET /starred` 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-0cb8c758943568de", "name": "Unused endpoint: GET /pricing/batch", "shortDescription": {"text": "Unused endpoint: GET /pricing/batch"}, "fullDescription": {"text": "`src/server/routes/library/tracks.ts` declares `GET /pricing/batch` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7a009b1a56794f45", "name": "Unused endpoint: POST /", "shortDescription": {"text": "Unused endpoint: POST /"}, "fullDescription": {"text": "`src/server/routes/library/tracks.ts` declares `POST /` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/19080"}, "properties": {"repository": "scobru/tunecamp", "repoUrl": "https://github.com/scobru/tunecamp", "branch": "main"}, "results": [{"ruleId": "scanner-1fb28f0eddc4c581", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/patch-ffmpeg.js:58"}, "properties": {"repobilityId": "0a7295a9ee6df373", "scanner": "scanner-primary", "fingerprint": "1fb28f0eddc4c581", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e8961c984efb1687", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/patch-slsk.js:50"}, "properties": {"repobilityId": "f6849fa2891eb346", "scanner": "scanner-primary", "fingerprint": "e8961c984efb1687", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-66bc36b022e112f9", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 webapp/src/zen.js:772"}, "properties": {"repobilityId": "7037a5e6baef55f3", "scanner": "scanner-primary", "fingerprint": "66bc36b022e112f9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-10cedf3abe859dac", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/zen.js:879"}, "properties": {"repobilityId": "c5f850b61837997e", "scanner": "scanner-primary", "fingerprint": "10cedf3abe859dac", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-075a77423522721f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/pwa.ts:6"}, "properties": {"repobilityId": "4d79c7e2b57998c6", "scanner": "scanner-primary", "fingerprint": "075a77423522721f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5f13db6d0cb0b556", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/RelatedTracks.tsx:73"}, "properties": {"repobilityId": "d0dfa7fcbf689652", "scanner": "scanner-primary", "fingerprint": "5f13db6d0cb0b556", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d7d4b023cea6a226", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/MetadataMatchModal.tsx:163"}, "properties": {"repobilityId": "a00221b711f004b9", "scanner": "scanner-primary", "fingerprint": "d7d4b023cea6a226", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c2907a7c433879ef", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/layout/Sidebar.tsx:297"}, "properties": {"repobilityId": "b9125062a289c955", "scanner": "scanner-primary", "fingerprint": "c2907a7c433879ef", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3da152327ac6b4d9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/player/QueuePanel.tsx:36"}, "properties": {"repobilityId": "2d5ae8de55f9b354", "scanner": "scanner-primary", "fingerprint": "3da152327ac6b4d9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3e15e1ade9beff1b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/player/PlayerBar.tsx:422"}, "properties": {"repobilityId": "dec25e7a5819c75e", "scanner": "scanner-primary", "fingerprint": "3e15e1ade9beff1b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5a6cb986114693c7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/components/player/PlayerBar.tsx:225"}, "properties": {"repobilityId": "dfe63e5530d297d1", "scanner": "scanner-primary", "fingerprint": "5a6cb986114693c7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7291e357bdb74b94", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/components/modals/CheckoutModal.tsx:76"}, "properties": {"repobilityId": "b7837525ed4f16b9", "scanner": "scanner-primary", "fingerprint": "7291e357bdb74b94", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c403a1f63d8f76e2", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminAssetModal.tsx:144"}, "properties": {"repobilityId": "474a8f008e210542", "scanner": "scanner-primary", "fingerprint": "c403a1f63d8f76e2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-4e210a17744bdd81", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminTrackModal.tsx:227"}, "properties": {"repobilityId": "a5e17b3e085751da", "scanner": "scanner-primary", "fingerprint": "4e210a17744bdd81", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-3d975e0ca198839d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AdminTrackModal.tsx:273"}, "properties": {"repobilityId": "7458a7e646cc3c77", "scanner": "scanner-primary", "fingerprint": "3d975e0ca198839d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-125e203f65923a45", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/SubscriptionModal.tsx:117"}, "properties": {"repobilityId": "614a12105d4f7499", "scanner": "scanner-primary", "fingerprint": "125e203f65923a45", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-f03acc9104c73079", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/SubscriptionModal.tsx:165"}, "properties": {"repobilityId": "36a979f2ef2ff57c", "scanner": "scanner-primary", "fingerprint": "f03acc9104c73079", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-74e2aa555fa288d0", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UnlockModal.tsx:60"}, "properties": {"repobilityId": "e1be2893b9eb49ef", "scanner": "scanner-primary", "fingerprint": "74e2aa555fa288d0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-7fad8e03b03a740a", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UploadTracksModal.tsx:202"}, "properties": {"repobilityId": "c7daef1e56411ab9", "scanner": "scanner-primary", "fingerprint": "7fad8e03b03a740a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-bd5f1bae64a93d73", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/UploadTracksModal.tsx:307"}, "properties": {"repobilityId": "6412a6d0935933c9", "scanner": "scanner-primary", "fingerprint": "bd5f1bae64a93d73", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0973e01ad3c4f1a4", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminArtistModal.tsx:257"}, "properties": {"repobilityId": "a4d728f736408644", "scanner": "scanner-primary", "fingerprint": "0973e01ad3c4f1a4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-b0785e3b29fa31bd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AdminArtistModal.tsx:331"}, "properties": {"repobilityId": "055d077f443dbdd6", "scanner": "scanner-primary", "fingerprint": "b0785e3b29fa31bd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b272e1212329d033", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/UnlockCodeManager.tsx:61"}, "properties": {"repobilityId": "f4f20ec0cd0733d0", "scanner": "scanner-primary", "fingerprint": "b272e1212329d033", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-3cd9811d290ac961", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/BatchTrackEditModal.tsx:146"}, "properties": {"repobilityId": "9e6a18972f2a7869", "scanner": "scanner-primary", "fingerprint": "3cd9811d290ac961", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-30b456f220ac6955", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/PlaylistModal.tsx:107"}, "properties": {"repobilityId": "8976163896c7dd5e", "scanner": "scanner-primary", "fingerprint": "30b456f220ac6955", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-05ac040a757df8b4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/PlaylistModal.tsx:145"}, "properties": {"repobilityId": "8fe4d01796a78d66", "scanner": "scanner-primary", "fingerprint": "05ac040a757df8b4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-71a97be7fd882417", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/ArtistMetadataPickerModal.tsx:111"}, "properties": {"repobilityId": "5703b79c7c908cb7", "scanner": "scanner-primary", "fingerprint": "71a97be7fd882417", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-319805c24249ccfd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AddBandcampTrackModal.tsx:129"}, "properties": {"repobilityId": "14f62d756db6bee0", "scanner": "scanner-primary", "fingerprint": "319805c24249ccfd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f40bd11a7cd77020", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AddTrackToUserPlaylistModal.tsx:184"}, "properties": {"repobilityId": "14aac5a3fe8f6f55", "scanner": "scanner-primary", "fingerprint": "f40bd11a7cd77020", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-0b6409ccee1aa5cb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/modals/AddTrackToUserPlaylistModal.tsx:265"}, "properties": {"repobilityId": "4b8b61055e182300", "scanner": "scanner-primary", "fingerprint": "0b6409ccee1aa5cb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-38ee198891abcc6b", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminReleaseModal.tsx:197"}, "properties": {"repobilityId": "251185baeaca4ed6", "scanner": "scanner-primary", "fingerprint": "38ee198891abcc6b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-120d1e6a888cf729", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/ArtistKeysModal.tsx:50"}, "properties": {"repobilityId": "f620f7a651e934cc", "scanner": "scanner-primary", "fingerprint": "120d1e6a888cf729", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-f7ee16e1c13d2f3f", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/CreatePostModal.tsx:117"}, "properties": {"repobilityId": "0899a236c0839918", "scanner": "scanner-primary", "fingerprint": "f7ee16e1c13d2f3f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-5636045af50ef09f", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/components/modals/CreatePostModal.tsx:218"}, "properties": {"repobilityId": "5255e892c2a965c1", "scanner": "scanner-primary", "fingerprint": "5636045af50ef09f", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-0fff5a455bf482b2", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/AdminUserModal.tsx:131"}, "properties": {"repobilityId": "b07d0509a666fb53", "scanner": "scanner-primary", "fingerprint": "0fff5a455bf482b2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-24cf64b73848cc4f", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/components/modals/CreateUserPlaylistModal.tsx:65"}, "properties": {"repobilityId": "663d1167d103d075", "scanner": "scanner-primary", "fingerprint": "24cf64b73848cc4f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-f8c4e51b46cd9d18", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/ui/PageHeader.tsx:39"}, "properties": {"repobilityId": "3f7367176a26c3e4", "scanner": "scanner-primary", "fingerprint": "f8c4e51b46cd9d18", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e5d6857ccded121e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/artist/ArtistFediversePanel.tsx:509"}, "properties": {"repobilityId": "3bd39f5f195157d4", "scanner": "scanner-primary", "fingerprint": "e5d6857ccded121e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0ef10887d26e723c", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/components/artist/ArtistFediversePanel.tsx:758"}, "properties": {"repobilityId": "7d7ca4b9d04df48d", "scanner": "scanner-primary", "fingerprint": "0ef10887d26e723c", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-343ab5db5cf3ebca", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/IntegrationsPanel.tsx:514"}, "properties": {"repobilityId": "6887f4b7f3476291", "scanner": "scanner-primary", "fingerprint": "343ab5db5cf3ebca", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4fc5a6b99b50a39e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/StoragePanel.tsx:140"}, "properties": {"repobilityId": "ce9fc40c2af61fbc", "scanner": "scanner-primary", "fingerprint": "4fc5a6b99b50a39e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-50924fe691da527f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/AdminSettingsPanel.tsx:554"}, "properties": {"repobilityId": "c426c0e2b5a4bc60", "scanner": "scanner-primary", "fingerprint": "50924fe691da527f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-47fad3e464dc429e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/components/admin/AdminFederationPanel.tsx:247"}, "properties": {"repobilityId": "deb8e527b13314fe", "scanner": "scanner-primary", "fingerprint": "47fad3e464dc429e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b26f32a0c137dd81", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/AdminReleaseEditor.tsx:609"}, "properties": {"repobilityId": "708b8da89efb87b0", "scanner": "scanner-primary", "fingerprint": "b26f32a0c137dd81", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-95a4ed4ee38cf722", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Network.tsx:269"}, "properties": {"repobilityId": "1532abf9441d5edc", "scanner": "scanner-primary", "fingerprint": "95a4ed4ee38cf722", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b57bb612b9a76483", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/Network.tsx:182"}, "properties": {"repobilityId": "81aba42253a9d3d4", "scanner": "scanner-primary", "fingerprint": "b57bb612b9a76483", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-b1a1ef0952b9e23a", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/Post.tsx:148"}, "properties": {"repobilityId": "8181a704f57effca", "scanner": "scanner-primary", "fingerprint": "b1a1ef0952b9e23a", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-67e220ab21aa17b1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Dig.tsx:163"}, "properties": {"repobilityId": "36f86d564149967e", "scanner": "scanner-primary", "fingerprint": "67e220ab21aa17b1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e59f0d1f974a804b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Favorites.tsx:256"}, "properties": {"repobilityId": "abe3edbbc25582aa", "scanner": "scanner-primary", "fingerprint": "e59f0d1f974a804b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7fefa35ca92ba7a1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Tracks.tsx:160"}, "properties": {"repobilityId": "73923e114212b8fa", "scanner": "scanner-primary", "fingerprint": "7fefa35ca92ba7a1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-84cc2789e8034b4d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Artists.tsx:215"}, "properties": {"repobilityId": "a62ce332be110f8c", "scanner": "scanner-primary", "fingerprint": "84cc2789e8034b4d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-954994639feb0bb3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Stats.tsx:63"}, "properties": {"repobilityId": "142d6a7f5372dacb", "scanner": "scanner-primary", "fingerprint": "954994639feb0bb3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8e40771246763263", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Playlists.tsx:214"}, "properties": {"repobilityId": "80c0c8d2797ab4c8", "scanner": "scanner-primary", "fingerprint": "8e40771246763263", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-265728890b515a37", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Board.tsx:474"}, "properties": {"repobilityId": "038fe100e8253b0c", "scanner": "scanner-primary", "fingerprint": "265728890b515a37", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-13248c926ca7a100", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/ArtistDetails.tsx:352"}, "properties": {"repobilityId": "0080d8a68fd28d27", "scanner": "scanner-primary", "fingerprint": "13248c926ca7a100", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5b1bcb0db22829c7", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 webapp/src/pages/ArtistDetails.tsx:284"}, "properties": {"repobilityId": "bdd28a6157592433", "scanner": "scanner-primary", "fingerprint": "5b1bcb0db22829c7", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-b400bbe73ef99c4b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/AlbumDetails.tsx:331"}, "properties": {"repobilityId": "ac956ed6351743a5", "scanner": "scanner-primary", "fingerprint": "b400bbe73ef99c4b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-06bf97525722b2dd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Search.tsx:287"}, "properties": {"repobilityId": "0136415b2f4fb940", "scanner": "scanner-primary", "fingerprint": "06bf97525722b2dd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5e2e7272baff4a68", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 webapp/src/pages/Store.tsx:49"}, "properties": {"repobilityId": "f91240ea0f1cca70", "scanner": "scanner-primary", "fingerprint": "5e2e7272baff4a68", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-3710f995bb38c096", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/Store.tsx:81"}, "properties": {"repobilityId": "cc36af9374484937", "scanner": "scanner-primary", "fingerprint": "3710f995bb38c096", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-25fca779ce4ef26e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 webapp/src/pages/ContentSearch.tsx:418"}, "properties": {"repobilityId": "4706a7951a7e1b29", "scanner": "scanner-primary", "fingerprint": "25fca779ce4ef26e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5593c5b50f10fd3b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/pages/ContentSearch.tsx:270"}, "properties": {"repobilityId": "e5dd85a41e1986a5", "scanner": "scanner-primary", "fingerprint": "5593c5b50f10fd3b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-cbb69c627fd6a26e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 webapp/src/hooks/useOwnedNFTs.ts:69"}, "properties": {"repobilityId": "b2f3dba1bb7a9e2d", "scanner": "scanner-primary", "fingerprint": "cbb69c627fd6a26e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-228e7d4757f878b1", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 deps/zen/index.js:443"}, "properties": {"repobilityId": "5a04faf0b44d3081", "scanner": "scanner-primary", "fingerprint": "228e7d4757f878b1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-e3707de6273a60f7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 deps/zen/index.js:591"}, "properties": {"repobilityId": "91d0949144586f29", "scanner": "scanner-primary", "fingerprint": "e3707de6273a60f7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fb48a0b7d38e5c6d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/index.ts:33"}, "properties": {"repobilityId": "867f5b4f120dafeb", "scanner": "scanner-primary", "fingerprint": "fb48a0b7d38e5c6d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-21ed23401a4c750d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/instrument.ts:26"}, "properties": {"repobilityId": "d38d2c1c50edda3e", "scanner": "scanner-primary", "fingerprint": "21ed23401a4c750d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c0dfc2b6b5a6cff4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/server.ts:130"}, "properties": {"repobilityId": "115023fd1e4ee9eb", "scanner": "scanner-primary", "fingerprint": "c0dfc2b6b5a6cff4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-47da7590f68b4fbd", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/__tests__/orphan-fix.test.ts:95"}, "properties": {"repobilityId": "80ae0e50a36f920d", "scanner": "scanner-primary", "fingerprint": "47da7590f68b4fbd", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3af3feb89ad19a8f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/providers/download/torrent.provider.ts:63"}, "properties": {"repobilityId": "3e7049227fe178e3", "scanner": "scanner-primary", "fingerprint": "3af3feb89ad19a8f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-770a37119966315d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/providers/streaming/soundcloud.provider.ts:73"}, "properties": {"repobilityId": "65226958304f3c22", "scanner": "scanner-primary", "fingerprint": "770a37119966315d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-dadbf4c95e8749ec", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/storage.ts:61"}, "properties": {"repobilityId": "01b20b3ed6276b44", "scanner": "scanner-primary", "fingerprint": "dadbf4c95e8749ec", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8566500851510dbc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/upload.ts:26"}, "properties": {"repobilityId": "ae7258b13e0a6369", "scanner": "scanner-primary", "fingerprint": "8566500851510dbc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-85abc76562d365a3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/releases.ts:179"}, "properties": {"repobilityId": "f4d4be41893740dd", "scanner": "scanner-primary", "fingerprint": "85abc76562d365a3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4cf260851fa12ce7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/artists.ts:458"}, "properties": {"repobilityId": "924a084052f704c4", "scanner": "scanner-primary", "fingerprint": "4cf260851fa12ce7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-47347e7eda629faf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/library/__tests__/upload_security.test.ts:97"}, "properties": {"repobilityId": "4012fe2c35d5cb2a", "scanner": "scanner-primary", "fingerprint": "47347e7eda629faf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c274cb3684d93c93", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/auth/users.ts:82"}, "properties": {"repobilityId": "3ca44f5920d93d6a", "scanner": "scanner-primary", "fingerprint": "c274cb3684d93c93", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-394ff8d83cac9a68", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/api/chat.ts:87"}, "properties": {"repobilityId": "ddd956833f43d93c", "scanner": "scanner-primary", "fingerprint": "394ff8d83cac9a68", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-04297d02fc6a1619", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/api/payments.ts:219"}, "properties": {"repobilityId": "f783a695e47f353e", "scanner": "scanner-primary", "fingerprint": "04297d02fc6a1619", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d73eb5daba60a440", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/search.ts:101"}, "properties": {"repobilityId": "4eec65b7ec608392", "scanner": "scanner-primary", "fingerprint": "d73eb5daba60a440", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-024ac2fef4afe781", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/activitypub.ts:37"}, "properties": {"repobilityId": "19ae50ec839a2129", "scanner": "scanner-primary", "fingerprint": "024ac2fef4afe781", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-568fc0c99059c04e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/proxy.ts:40"}, "properties": {"repobilityId": "30fdccec9eae3bb2", "scanner": "scanner-primary", "fingerprint": "568fc0c99059c04e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-daf33a9f7810b9b9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/network/__tests__/activitypub.bench.test.ts:110"}, "properties": {"repobilityId": "2a372e4bb967183f", "scanner": "scanner-primary", "fingerprint": "daf33a9f7810b9b9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5e6a0a28622e3a08", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/backup.ts:52"}, "properties": {"repobilityId": "fbe387554f1795ce", "scanner": "scanner-primary", "fingerprint": "5e6a0a28622e3a08", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-64ce4ab628b3f7d7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/browser.ts:188"}, "properties": {"repobilityId": "3958f57240fa3397", "scanner": "scanner-primary", "fingerprint": "64ce4ab628b3f7d7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e1ec40c8b9f1df1c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/routes/admin/admin.ts:446"}, "properties": {"repobilityId": "8ecd58fd4870acd0", "scanner": "scanner-primary", "fingerprint": "e1ec40c8b9f1df1c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-71cdef6843e04e3e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/soulseek.ts:69"}, "properties": {"repobilityId": "398b45e35b03a0ec", "scanner": "scanner-primary", "fingerprint": "71cdef6843e04e3e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8ca14757d19cf7c2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/telegram-bot.ts:214"}, "properties": {"repobilityId": "d214cb5754636d7c", "scanner": "scanner-primary", "fingerprint": "8ca14757d19cf7c2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-de9c966eecf6a705", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/integrations/torrent.service.ts:54"}, "properties": {"repobilityId": "aa71276b2bfc803d", "scanner": "scanner-primary", "fingerprint": "de9c966eecf6a705", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d4cb20e9ed45c81f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/live/hls.service.ts:81"}, "properties": {"repobilityId": "3954d21e63b817fd", "scanner": "scanner-primary", "fingerprint": "d4cb20e9ed45c81f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5f2f7b91b21492a1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/auth/auth.service.ts:14"}, "properties": {"repobilityId": "abec9b4d177a6847", "scanner": "scanner-primary", "fingerprint": "5f2f7b91b21492a1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e1343ce6fc596802", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/media/ffmpeg.ts:52"}, "properties": {"repobilityId": "1455719ed10356a5", "scanner": "scanner-primary", "fingerprint": "e1343ce6fc596802", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6d25d6eef0b0ac2e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/media/media-engine.ts:484"}, "properties": {"repobilityId": "c43c0a9d18c41f0a", "scanner": "scanner-primary", "fingerprint": "6d25d6eef0b0ac2e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a74ebcc3a98164ae", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/network/federated-discovery.service.ts:257"}, "properties": {"repobilityId": "06c4368fe4509629", "scanner": "scanner-primary", "fingerprint": "a74ebcc3a98164ae", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0a18186e4d8bdd6f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/network/rss.service.ts:106"}, "properties": {"repobilityId": "315857f165ea13af", "scanner": "scanner-primary", "fingerprint": "0a18186e4d8bdd6f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-094ce12184677589", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/catalog.service.ts:36"}, "properties": {"repobilityId": "5bc29bfd454672f6", "scanner": "scanner-primary", "fingerprint": "094ce12184677589", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ff080526b4ca45e6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/price.ts:52"}, "properties": {"repobilityId": "8fa3591e70ece87e", "scanner": "scanner-primary", "fingerprint": "ff080526b4ca45e6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-44230d3574f155b3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/localization.service.ts:58"}, "properties": {"repobilityId": "74ed6a7913f517fe", "scanner": "scanner-primary", "fingerprint": "44230d3574f155b3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b10d32d878a6c32e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/scanner.service.ts:24"}, "properties": {"repobilityId": "d6a3ed5151a1ad22", "scanner": "scanner-primary", "fingerprint": "b10d32d878a6c32e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-573db286ecd11453", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/library-sync.ts:86"}, "properties": {"repobilityId": "0fdfdd900d1bb2d5", "scanner": "scanner-primary", "fingerprint": "573db286ecd11453", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-270f33753fd5c101", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/server/modules/catalog/lifecycle.service.ts:150"}, "properties": {"repobilityId": "c207be5caf5a3496", "scanner": "scanner-primary", "fingerprint": "270f33753fd5c101", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-b7bcb913c7ff3fba", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/lifecycle.service.ts:37"}, "properties": {"repobilityId": "2f3aa7e9ca512a46", "scanner": "scanner-primary", "fingerprint": "b7bcb913c7ff3fba", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c2713ed0aa396898", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/scanner.ts:251"}, "properties": {"repobilityId": "876285de8aed536d", "scanner": "scanner-primary", "fingerprint": "c2713ed0aa396898", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9a0dac18b5851d74", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/maintenance.service.ts:29"}, "properties": {"repobilityId": "5a66ea702578094d", "scanner": "scanner-primary", "fingerprint": "9a0dac18b5851d74", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a7d3b787084f2a32", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/download.service.ts:32"}, "properties": {"repobilityId": "ee3e2d67e98ad0fb", "scanner": "scanner-primary", "fingerprint": "a7d3b787084f2a32", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f352d394568d52e3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/maintenance.startup.ts:35"}, "properties": {"repobilityId": "739af1bce393030d", "scanner": "scanner-primary", "fingerprint": "f352d394568d52e3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3ca66b6b3c734186", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/catalog/autotagger.service.ts:62"}, "properties": {"repobilityId": "edb6f9b5444f30ce", "scanner": "scanner-primary", "fingerprint": "3ca66b6b3c734186", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8581bb5664598b45", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/fedify/fedify.ts:358"}, "properties": {"repobilityId": "c28e80d300611bd3", "scanner": "scanner-primary", "fingerprint": "8581bb5664598b45", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0547b155a014c393", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/workers/task-manager.ts:59"}, "properties": {"repobilityId": "9495bf8e00654586", "scanner": "scanner-primary", "fingerprint": "0547b155a014c393", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e93427cd19bff8e1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/publishing/publishing.service.ts:50"}, "properties": {"repobilityId": "0dc7323181f9591e", "scanner": "scanner-primary", "fingerprint": "e93427cd19bff8e1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4e985661bbde8b24", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.service.ts:96"}, "properties": {"repobilityId": "3ebf411ac8d2c6ad", "scanner": "scanner-primary", "fingerprint": "4e985661bbde8b24", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6eeca4d6ff01536a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.transport.ts:36"}, "properties": {"repobilityId": "c242f51975127788", "scanner": "scanner-primary", "fingerprint": "6eeca4d6ff01536a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8582167fda5d3d03", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/activitypub/activitypub.delivery-queue.ts:77"}, "properties": {"repobilityId": "07989695b647a2d7", "scanner": "scanner-primary", "fingerprint": "8582167fda5d3d03", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-caacb61ce72a385e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/scrobble/scrobble.service.ts:24"}, "properties": {"repobilityId": "0eb80bd4c267098a", "scanner": "scanner-primary", "fingerprint": "caacb61ce72a385e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6faa6f916bf2854c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/modules/streaming/streaming.service.ts:67"}, "properties": {"repobilityId": "0429f334e55b1213", "scanner": "scanner-primary", "fingerprint": "6faa6f916bf2854c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0e06fa40130069c3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/repositories/artist.repository.ts:72"}, "properties": {"repobilityId": "4e5ef0f8b34ab63a", "scanner": "scanner-primary", "fingerprint": "0e06fa40130069c3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-78c25cc6cfce369e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/config.ts:73"}, "properties": {"repobilityId": "61258ade3ef20ad3", "scanner": "scanner-primary", "fingerprint": "78c25cc6cfce369e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6b3d5d516c09a8f1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/provider.ts:34"}, "properties": {"repobilityId": "929a6c4a33018baa", "scanner": "scanner-primary", "fingerprint": "6b3d5d516c09a8f1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d36245b45370c7af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/plugin-loader.ts:42"}, "properties": {"repobilityId": "8f2c2df3357c7883", "scanner": "scanner-primary", "fingerprint": "d36245b45370c7af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bd21fe002d9aba9b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/database.ts:52"}, "properties": {"repobilityId": "c77e00c65f8b29fc", "scanner": "scanner-primary", "fingerprint": "bd21fe002d9aba9b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ef92df3cf6791238", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/server/core/managers/social.ts:23"}, "properties": {"repobilityId": "02f4d89b44ad1e85", "scanner": "scanner-primary", "fingerprint": "ef92df3cf6791238", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-036f591d7fe0f2ca", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/migrate-dedupe.ts:38"}, "properties": {"repobilityId": "3a37ef3c9cbb00a3", "scanner": "scanner-primary", "fingerprint": "036f591d7fe0f2ca", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ad040eec09a66121", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/relink-tracks.ts:32"}, "properties": {"repobilityId": "6d0507259f27626e", "scanner": "scanner-primary", "fingerprint": "ad040eec09a66121", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9c7e6e4332b34a02", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/backup.ts:33"}, "properties": {"repobilityId": "ac1d79150926148f", "scanner": "scanner-primary", "fingerprint": "9c7e6e4332b34a02", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-78778c500a972b0f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/generate-codes.ts:105"}, "properties": {"repobilityId": "b1622e9d4bba02b7", "scanner": "scanner-primary", "fingerprint": "78778c500a972b0f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-821a06991cd3f07c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/migrate-visibility.ts:28"}, "properties": {"repobilityId": "789207f31f6f200d", "scanner": "scanner-primary", "fingerprint": "821a06991cd3f07c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3701f8df6e6c80c8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/restore.ts:18"}, "properties": {"repobilityId": "07175b0fa26ee81d", "scanner": "scanner-primary", "fingerprint": "3701f8df6e6c80c8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d017e65b98706038", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/clean-folders.ts:43"}, "properties": {"repobilityId": "bb93348917313400", "scanner": "scanner-primary", "fingerprint": "d017e65b98706038", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-006551ed3d732efc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/tools/fix-paths.ts:21"}, "properties": {"repobilityId": "bdadeeb72ac22217", "scanner": "scanner-primary", "fingerprint": "006551ed3d732efc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a19990c988526f02", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 plugins/demo-provider.js:53"}, "properties": {"repobilityId": "353e49285564d5f7", "scanner": "scanner-primary", "fingerprint": "a19990c988526f02", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-835eae4c7f17a2f8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "c52b67b7965ef095", "scanner": "scanner-primary", "fingerprint": "835eae4c7f17a2f8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 28}}}]}, {"ruleId": "scanner-835eae4c7f17a2f8", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "e89a82df05049812", "scanner": "scanner-primary", "fingerprint": "835eae4c7f17a2f8", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 91}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-b91ec66944e6fd72", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in package.json:20"}, "properties": {"repobilityId": "40fa5506c1a3b684", "scanner": "scanner-primary", "fingerprint": "b91ec66944e6fd72", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-cb7405c4677dd1a7", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/components/modals/CreatePostModal.tsx:218"}, "properties": {"repobilityId": "bfc3ce7ff17ead45", "scanner": "scanner-primary", "fingerprint": "cb7405c4677dd1a7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/src/components/modals/CreatePostModal.tsx"}, "region": {"startLine": 218}}}]}, {"ruleId": "scanner-fb460cf1b155a92c", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/components/artist/ArtistFediversePanel.tsx:758"}, "properties": {"repobilityId": "f9e441ff4c0e10c5", "scanner": "scanner-primary", "fingerprint": "fb460cf1b155a92c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/src/components/artist/ArtistFediversePanel.tsx"}, "region": {"startLine": 758}}}]}, {"ruleId": "scanner-cc2b35455149543d", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/Network.tsx:182"}, "properties": {"repobilityId": "f43b75a44fba7f39", "scanner": "scanner-primary", "fingerprint": "cc2b35455149543d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/src/pages/Network.tsx"}, "region": {"startLine": 182}}}]}, {"ruleId": "scanner-251eaea6ec0823c9", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/Post.tsx:148"}, "properties": {"repobilityId": "3a02f2c9c135c04c", "scanner": "scanner-primary", "fingerprint": "251eaea6ec0823c9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/src/pages/Post.tsx"}, "region": {"startLine": 148}}}]}, {"ruleId": "scanner-fbb455dd01869b15", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in webapp/src/pages/ArtistDetails.tsx:284"}, "properties": {"repobilityId": "17b7b78b834321b4", "scanner": "scanner-primary", "fingerprint": "fbb455dd01869b15", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/src/pages/ArtistDetails.tsx"}, "region": {"startLine": 284}}}]}, {"ruleId": "scanner-f9cf26fba99b8221", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in webapp/src/services/api.ts:64"}, "properties": {"repobilityId": "ac019ebef6dec571", "scanner": "scanner-primary", "fingerprint": "f9cf26fba99b8221", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "webapp/src/services/api.ts"}, "region": {"startLine": 64}}}]}, {"ruleId": "scanner-33ce4224fdabc5c2", "level": "error", "message": {"text": "Insecure pattern 'exec_used' in src/server/routes/admin/backup.ts:76"}, "properties": {"repobilityId": "741ce54702f6c137", "scanner": "scanner-primary", "fingerprint": "33ce4224fdabc5c2", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "exec_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/server/routes/admin/backup.ts"}, "region": {"startLine": 76}}}]}, {"ruleId": "scanner-bb196a6aced49c43", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in src/server/modules/live/hls.service.ts:1"}, "properties": {"repobilityId": "b955c1ec36b514f8", "scanner": "scanner-primary", "fingerprint": "bb196a6aced49c43", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/server/modules/live/hls.service.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-056df237fc8a9fd3", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in src/server/modules/catalog/localization.service.ts:3"}, "properties": {"repobilityId": "c4e5693acaedcae2", "scanner": "scanner-primary", "fingerprint": "056df237fc8a9fd3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/server/modules/catalog/localization.service.ts"}, "region": {"startLine": 3}}}]}, {"ruleId": "scanner-f5c6e806454f7092", "level": "warning", "message": {"text": "Install-time lifecycle script performs network/shell-sensitive actions"}, "properties": {"repobilityId": "edeab51902066991", "scanner": "scanner-primary", "fingerprint": "f5c6e806454f7092", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "npm", "install-scripts"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-cac75a3d19a4216f", "level": "note", "message": {"text": "Very large file: webapp/src/zen.js (8441 lines)"}, "properties": {"repobilityId": "f8bfd9e6bdd80349", "scanner": "scanner-primary", "fingerprint": "cac75a3d19a4216f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-0299d22352dcdb2d", "level": "note", "message": {"text": "Very large file: webapp/src/components/artist/ArtistFediversePanel.tsx (1290 lines)"}, "properties": {"repobilityId": "6761d5b82e09b54a", "scanner": "scanner-primary", "fingerprint": "0299d22352dcdb2d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-06f583af72fc35c2", "level": "note", "message": {"text": "Very large file: webapp/src/pages/AdminReleaseEditor.tsx (1470 lines)"}, "properties": {"repobilityId": "1e2d0f920a728bee", "scanner": "scanner-primary", "fingerprint": "06f583af72fc35c2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-74f6cc3aa033cc46", "level": "note", "message": {"text": "Very large file: webapp/src/pages/Profile.tsx (1509 lines)"}, "properties": {"repobilityId": "a189f67bd7910b4c", "scanner": "scanner-primary", "fingerprint": "74f6cc3aa033cc46", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b208aa87e38cf32e", "level": "note", "message": {"text": "Very large file: webapp/src/pages/ContentSearch.tsx (967 lines)"}, "properties": {"repobilityId": "745c784743ea0c38", "scanner": "scanner-primary", "fingerprint": "b208aa87e38cf32e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-087e55ff98931e77", "level": "note", "message": {"text": "Very large file: deps/zen/index.js (5134 lines)"}, "properties": {"repobilityId": "b14ce1de15435a5c", "scanner": "scanner-primary", "fingerprint": "087e55ff98931e77", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-f127319e12ba1990", "level": "note", "message": {"text": "Very large file: src/server/routes/api/payments.ts (1058 lines)"}, "properties": {"repobilityId": "1636f88f41d6dc63", "scanner": "scanner-primary", "fingerprint": "f127319e12ba1990", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-06bc0257f6397024", "level": "note", "message": {"text": "Very large file: src/server/routes/admin/admin.ts (2206 lines)"}, "properties": {"repobilityId": "b435ed764788605f", "scanner": "scanner-primary", "fingerprint": "06bc0257f6397024", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-84c921a8ac3e84cc", "level": "note", "message": {"text": "Very large file: src/server/modules/activitypub/activitypub.service.ts (1928 lines)"}, "properties": {"repobilityId": "0e189d82e82d332f", "scanner": "scanner-primary", "fingerprint": "84c921a8ac3e84cc", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ad76a0f04715c0d4", "level": "note", "message": {"text": "Very large file: src/server/core/database.ts (1118 lines)"}, "properties": {"repobilityId": "ef1bb8d0cfb46925", "scanner": "scanner-primary", "fingerprint": "ad76a0f04715c0d4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-46191edd49d0d209", "level": "note", "message": {"text": "236 TODO/FIXME markers"}, "properties": {"repobilityId": "4b38c118003e07d2", "scanner": "scanner-primary", "fingerprint": "46191edd49d0d209", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["maintenance"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "e83a6f14e6b30c78", "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": "bc674b7c8f58c93f", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "d14cce5dae35827e", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "cd47b3159f6df382", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "cc5065b7244e5821", "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": "ff9dae4934e795e4", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-b347463739865ff5", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: agents/tc-adoption-ux/SKILL.md"}, "properties": {"repobilityId": "b3337a4b3c0aa7e6", "scanner": "scanner-primary", "fingerprint": "b347463739865ff5", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "skill_file"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agents/tc-adoption-ux/SKILL.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b96fd5a3219e07ee", "level": "none", "message": {"text": "Commented-code block (8 lines) in scripts/patch-slsk.js:8"}, "properties": {"repobilityId": "b28947e301f96536", "scanner": "scanner-primary", "fingerprint": "b96fd5a3219e07ee", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e8ee64ee0a376d8b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/public/sw.js:35"}, "properties": {"repobilityId": "a286bcb44c459947", "scanner": "scanner-primary", "fingerprint": "e8ee64ee0a376d8b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9e80695b2cfb341c", "level": "none", "message": {"text": "Commented-code block (7 lines) in webapp/src/zen.js:1130"}, "properties": {"repobilityId": "57462ff491f1aba0", "scanner": "scanner-primary", "fingerprint": "9e80695b2cfb341c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7c91e7903c483264", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/src/zen.js:1369"}, "properties": {"repobilityId": "2f61a72aeb2e4ae4", "scanner": "scanner-primary", "fingerprint": "7c91e7903c483264", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cac8bd5b5c289111", "level": "none", "message": {"text": "Commented-code block (6 lines) in webapp/src/stores/useConfigStore.ts:35"}, "properties": {"repobilityId": "7c6ace9a55f34470", "scanner": "scanner-primary", "fingerprint": "cac8bd5b5c289111", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e26a908d8e756908", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 webapp/src/components/modals/CheckoutModal.tsx:52"}, "properties": {"repobilityId": "94aa8e452b078759", "scanner": "scanner-primary", "fingerprint": "e26a908d8e756908", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f3aaae8bbed260fd", "level": "none", "message": {"text": "Commented-code block (7 lines) in deps/zen/index.js:708"}, "properties": {"repobilityId": "2f6eff2388c940d9", "scanner": "scanner-primary", "fingerprint": "f3aaae8bbed260fd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bd2ad3bc7dd415aa", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 deps/zen/index.js:2114"}, "properties": {"repobilityId": "f10fdb3ef1b7bae4", "scanner": "scanner-primary", "fingerprint": "bd2ad3bc7dd415aa", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-21fe00ab18cb066c", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/utils/networkUtils.test.ts:17"}, "properties": {"repobilityId": "84e4f06a368ca5f9", "scanner": "scanner-primary", "fingerprint": "21fe00ab18cb066c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-774b00004ba4cbf0", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/server.ts:173"}, "properties": {"repobilityId": "8f272eea916ee68c", "scanner": "scanner-primary", "fingerprint": "774b00004ba4cbf0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-fc53c3a36c710402", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/server/__tests__/rateLimit.integration.test.ts:90"}, "properties": {"repobilityId": "00c67ddb6981faa4", "scanner": "scanner-primary", "fingerprint": "fc53c3a36c710402", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-80c5c72bb27ab6d5", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/server/__tests__/error-handling.test.ts:6"}, "properties": {"repobilityId": "3ee3e72458a4ee58", "scanner": "scanner-primary", "fingerprint": "80c5c72bb27ab6d5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ef346f54bd9e7d4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/common/network.ts:29"}, "properties": {"repobilityId": "c6a73b96c79ae096", "scanner": "scanner-primary", "fingerprint": "0ef346f54bd9e7d4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0d381989fbd27b44", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/utils/deezer.ts:8"}, "properties": {"repobilityId": "5ad820dfbedd3091", "scanner": "scanner-primary", "fingerprint": "0d381989fbd27b44", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a448c52e9fa89d16", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/utils/spotify.ts:118"}, "properties": {"repobilityId": "f54900e19c60f7af", "scanner": "scanner-primary", "fingerprint": "a448c52e9fa89d16", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-93343c135878aacd", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/providers/scrobble/listenbrainz.provider.ts:35"}, "properties": {"repobilityId": "4487b0fc7149b3c3", "scanner": "scanner-primary", "fingerprint": "93343c135878aacd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a13fc5e2edf3de63", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/providers/scrobble/lastfm.provider.ts:55"}, "properties": {"repobilityId": "bb7ac956b4509d55", "scanner": "scanner-primary", "fingerprint": "a13fc5e2edf3de63", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-42c310d097377ffa", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/server/routes/api/payments.ts:205"}, "properties": {"repobilityId": "f0129976549b6a65", "scanner": "scanner-primary", "fingerprint": "42c310d097377ffa", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-60e8ccf2def44e8a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/routes/admin/metadata.ts:278"}, "properties": {"repobilityId": "3b826aefc63f64c7", "scanner": "scanner-primary", "fingerprint": "60e8ccf2def44e8a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2dbb223a8f9b5f9b", "level": "note", "message": {"text": "Legacy-named symbol `normOld` in src/server/routes/admin/browser.ts:184"}, "properties": {"repobilityId": "b31ccd1e2bd24149", "scanner": "scanner-primary", "fingerprint": "2dbb223a8f9b5f9b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-2505107453d4be56", "level": "note", "message": {"text": "Legacy-named symbol `admin_old` in src/server/modules/auth/auth.service.ts:163"}, "properties": {"repobilityId": "4d9a8cd61b57e2be", "scanner": "scanner-primary", "fingerprint": "2505107453d4be56", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-76cfb9339759dbbb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/auth/auth.service.ts:680"}, "properties": {"repobilityId": "e57c5459afc9473f", "scanner": "scanner-primary", "fingerprint": "76cfb9339759dbbb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-67328e909db9a1aa", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/modules/media/ffmpeg.ts:69"}, "properties": {"repobilityId": "5c5d82dc3c7a5727", "scanner": "scanner-primary", "fingerprint": "67328e909db9a1aa", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-86954e16d0115f57", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/server/modules/media/media-engine.ts:245"}, "properties": {"repobilityId": "d2ad616fa271519c", "scanner": "scanner-primary", "fingerprint": "86954e16d0115f57", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4855f3f1c76b25a6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/network/catalog-cache.service.ts:90"}, "properties": {"repobilityId": "0c288b9f0554275f", "scanner": "scanner-primary", "fingerprint": "4855f3f1c76b25a6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0dadad9c1359fcd0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/catalog/__tests__/catalog.service.test.ts:3"}, "properties": {"repobilityId": "a125ad06e8fcad2a", "scanner": "scanner-primary", "fingerprint": "0dadad9c1359fcd0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-a775485c9cce2a59", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/publishing/publishing.service.ts:137"}, "properties": {"repobilityId": "88bfd26852fdd335", "scanner": "scanner-primary", "fingerprint": "a775485c9cce2a59", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-505afd252475072b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/server/modules/activitypub/activitypub.service.ts:1605"}, "properties": {"repobilityId": "429b728cc52b4cb7", "scanner": "scanner-primary", "fingerprint": "505afd252475072b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-86564ebed9b49b0a", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/server/modules/activitypub/activitypub.transport.ts:25"}, "properties": {"repobilityId": "5353cab39eb15e24", "scanner": "scanner-primary", "fingerprint": "86564ebed9b49b0a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9cac7ce15e72817b", "level": "note", "message": {"text": "31 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "1a52e2d4d46a6e40", "scanner": "scanner-primary", "fingerprint": "9cac7ce15e72817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-59bc4afe4629ae62", "level": "warning", "message": {"text": "Frontend route `/albums/:idOrSlug` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "97fb350dddedb82c", "scanner": "scanner-primary", "fingerprint": "59bc4afe4629ae62", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-f196fec02eba23a8", "level": "warning", "message": {"text": "Frontend route `/releases/:idOrSlug` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "6c6edb20c048bcfe", "scanner": "scanner-primary", "fingerprint": "f196fec02eba23a8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e2102210c111e0b2", "level": "warning", "message": {"text": "Frontend route `/artists/:idOrSlug` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "19d6b4d0c2c44523", "scanner": "scanner-primary", "fingerprint": "e2102210c111e0b2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-49080945f811eec2", "level": "warning", "message": {"text": "Frontend route `/playlists/:id` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "bb15d79e7b4692e6", "scanner": "scanner-primary", "fingerprint": "49080945f811eec2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-ce0228cd20f5e113", "level": "warning", "message": {"text": "Frontend route `/my-playlists/:id` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "094cc829f9aa8bf7", "scanner": "scanner-primary", "fingerprint": "ce0228cd20f5e113", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-7f25f90c8145e7c3", "level": "warning", "message": {"text": "Frontend route `/post/:slug` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "c4d858d5c23b86ff", "scanner": "scanner-primary", "fingerprint": "7f25f90c8145e7c3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3c71ba96f2aa2bc0", "level": "warning", "message": {"text": "Frontend route `/share/:id` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "e2d617f7f3d599a7", "scanner": "scanner-primary", "fingerprint": "3c71ba96f2aa2bc0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-456bc989f5a7c863", "level": "warning", "message": {"text": "Frontend route `/admin/release/:id/edit` has no Link/navigate to it \u2014 webapp/src/App.tsx"}, "properties": {"repobilityId": "dc186c6cee578256", "scanner": "scanner-primary", "fingerprint": "456bc989f5a7c863", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e8fd072ec8a471e9", "level": "error", "message": {"text": "Dangling fetch: GET /api/payments/onramp-config (webapp/src/components/modals/CheckoutModal.tsx:52)"}, "properties": {"repobilityId": "5adb9729299450a8", "scanner": "scanner-primary", "fingerprint": "e8fd072ec8a471e9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2894af9ed3c49a9c", "level": "error", "message": {"text": "Dangling fetch: GET /api/payments/rate/USD (webapp/src/components/modals/CheckoutModal.tsx:101)"}, "properties": {"repobilityId": "c38f77dd9243a180", "scanner": "scanner-primary", "fingerprint": "2894af9ed3c49a9c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-400a6cb2887cc5fa", "level": "error", "message": {"text": "Dangling fetch: POST /api/payments/stripe/create-session (webapp/src/components/modals/CheckoutModal.tsx:153)"}, "properties": {"repobilityId": "e516547e7e250e59", "scanner": "scanner-primary", "fingerprint": "400a6cb2887cc5fa", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-776998768a5e5374", "level": "error", "message": {"text": "Dangling fetch: POST /api/payments/verify (webapp/src/components/modals/CheckoutModal.tsx:325)"}, "properties": {"repobilityId": "5f3dc44d9e8f0ed2", "scanner": "scanner-primary", "fingerprint": "776998768a5e5374", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-2167ed4b9b80c5e8", "level": "error", "message": {"text": "Dangling fetch: GET /api/payments/rate/USD (webapp/src/components/modals/SubscriptionModal.tsx:51)"}, "properties": {"repobilityId": "8de3d4eef97445d9", "scanner": "scanner-primary", "fingerprint": "2167ed4b9b80c5e8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d3639de456ec5df5", "level": "error", "message": {"text": "Dangling fetch: GET /api/payments/onramp-config (webapp/src/pages/AdminReleaseEditor.tsx:179)"}, "properties": {"repobilityId": "94a74b7d86064779", "scanner": "scanner-primary", "fingerprint": "d3639de456ec5df5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-090c682b495a098b", "level": "error", "message": {"text": "Dangling fetch: GET /api/tracks/${track.id}/lyrics (webapp/src/pages/AdminReleaseEditor.tsx:1213)"}, "properties": {"repobilityId": "5af30f285f51756d", "scanner": "scanner-primary", "fingerprint": "090c682b495a098b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3c286ec4c9f3fb6d", "level": "error", "message": {"text": "Dangling fetch: POST /api/payments/verify (webapp/src/hooks/usePurchases.ts:39)"}, "properties": {"repobilityId": "2217c102268826fe", "scanner": "scanner-primary", "fingerprint": "3c286ec4c9f3fb6d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-668fdf539669b23f", "level": "error", "message": {"text": "Dangling fetch: GET /playlist/${id} (src/server/utils/deezer.ts:14)"}, "properties": {"repobilityId": "ab35247ab933588f", "scanner": "scanner-primary", "fingerprint": "668fdf539669b23f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-982c965ce20af72c", "level": "error", "message": {"text": "Dangling fetch: GET /search/track?q=${encodeURIComponent(query)}&limit=${limit} (src/server/utils/deezer.ts:18)"}, "properties": {"repobilityId": "164665136e4f12f5", "scanner": "scanner-primary", "fingerprint": "982c965ce20af72c", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "helper:request"]}}, {"ruleId": "scanner-25cc61c9aa0d1768", "level": "error", "message": {"text": "Dangling fetch: GET https://itunes.apple.com/search?term=jack+jackson&limit=1 (src/server/routes/admin/admin.ts:1869)"}, "properties": {"repobilityId": "57db13e6b443e78d", "scanner": "scanner-primary", "fingerprint": "25cc61c9aa0d1768", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-a1164fb3aa0e4440", "level": "error", "message": {"text": "Dangling fetch: GET https://musicbrainz.org/ws/2/release/?query=test&fmt=json (src/server/routes/admin/admin.ts:1880)"}, "properties": {"repobilityId": "ec8488fe99c04a4c", "scanner": "scanner-primary", "fingerprint": "a1164fb3aa0e4440", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-63dae6a1a2d1a06d", "level": "error", "message": {"text": "Dangling fetch: GET https://api.deezer.com/version (src/server/routes/admin/admin.ts:1927)"}, "properties": {"repobilityId": "4b21bdbff3429860", "scanner": "scanner-primary", "fingerprint": "63dae6a1a2d1a06d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c07af3943aaac09a", "level": "error", "message": {"text": "Dangling fetch: HEAD https://open.spotify.com (src/server/routes/admin/admin.ts:1948)"}, "properties": {"repobilityId": "3fa7afc99c7df0dd", "scanner": "scanner-primary", "fingerprint": "c07af3943aaac09a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-129067ce0bc37793", "level": "error", "message": {"text": "Dangling fetch: HEAD https://soundcloud.com (src/server/routes/admin/admin.ts:1956)"}, "properties": {"repobilityId": "6e42175ba9074f7e", "scanner": "scanner-primary", "fingerprint": "129067ce0bc37793", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4be8bc285740e57d", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:53)"}, "properties": {"repobilityId": "e2b8b984c4800a5d", "scanner": "scanner-primary", "fingerprint": "4be8bc285740e57d", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7396a186b4e58b28", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:107)"}, "properties": {"repobilityId": "c4330aa46641ce09", "scanner": "scanner-primary", "fingerprint": "7396a186b4e58b28", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-75df8cf996cf6595", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:153)"}, "properties": {"repobilityId": "10781adacc05bfa9", "scanner": "scanner-primary", "fingerprint": "75df8cf996cf6595", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8e723aa381f71933", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:195)"}, "properties": {"repobilityId": "e0f3587a93759624", "scanner": "scanner-primary", "fingerprint": "8e723aa381f71933", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-34ef5bce206cf276", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (src/server/modules/ai/openrouter.service.ts:243)"}, "properties": {"repobilityId": "04e024cc3f605eb7", "scanner": "scanner-primary", "fingerprint": "34ef5bce206cf276", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1efba9e730cc38d3", "level": "error", "message": {"text": "Dangling fetch: GET https://api.coingecko.com/api/v3/simple/price?ids=ethereum&vs_currencies=usd (src/server/modules/catalog/price.ts:30)"}, "properties": {"repobilityId": "31a95ad164fa9a6c", "scanner": "scanner-primary", "fingerprint": "1efba9e730cc38d3", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-55b3e4f90db2f1a7", "level": "error", "message": {"text": "Dangling fetch: GET https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD (src/server/modules/catalog/price.ts:47)"}, "properties": {"repobilityId": "3b0bee63d3e33fbc", "scanner": "scanner-primary", "fingerprint": "55b3e4f90db2f1a7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-82fb7c0e688aa956", "level": "error", "message": {"text": "Dangling fetch: POST https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart (src/server/modules/storage/google-drive.service.ts:61)"}, "properties": {"repobilityId": "2459714b917e0674", "scanner": "scanner-primary", "fingerprint": "82fb7c0e688aa956", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-15b463815e3790b8", "level": "error", "message": {"text": "Dangling fetch: POST https://oauth2.googleapis.com/token (src/server/modules/storage/google-drive.service.ts:72)"}, "properties": {"repobilityId": "a63a328234d60be9", "scanner": "scanner-primary", "fingerprint": "15b463815e3790b8", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-e51444842bc3cd6e", "level": "error", "message": {"text": "Dangling fetch: GET https://www.googleapis.com/oauth2/v2/userinfo (src/server/modules/storage/google-drive.service.ts:83)"}, "properties": {"repobilityId": "d30b18835be3c7bf", "scanner": "scanner-primary", "fingerprint": "e51444842bc3cd6e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-2bf917f783646d54", "level": "error", "message": {"text": "Dangling fetch: POST https://oauth2.googleapis.com/token (src/server/modules/storage/google-drive.service.ts:121)"}, "properties": {"repobilityId": "48c27cc494ac0e93", "scanner": "scanner-primary", "fingerprint": "2bf917f783646d54", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-eedaf35571c84a59", "level": "error", "message": {"text": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files (src/server/modules/storage/google-drive.service.ts:145)"}, "properties": {"repobilityId": "bde296f14b18d3df", "scanner": "scanner-primary", "fingerprint": "eedaf35571c84a59", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-07d8f87b71fbeeb5", "level": "error", "message": {"text": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files/${fileId} (src/server/modules/storage/google-drive.service.ts:190)"}, "properties": {"repobilityId": "dedd2e920b846d31", "scanner": "scanner-primary", "fingerprint": "07d8f87b71fbeeb5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-008e08b3b1981d05", "level": "error", "message": {"text": "Dangling fetch: GET https://www.googleapis.com/drive/v3/files/${fileId} (src/server/modules/storage/google-drive.service.ts:203)"}, "properties": {"repobilityId": "98fad0cb9c7b52cd", "scanner": "scanner-primary", "fingerprint": "008e08b3b1981d05", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "axios"]}}, {"ruleId": "scanner-684f0e83ba7e1558", "level": "note", "message": {"text": "Unused endpoint: GET "}, "properties": {"repobilityId": "7918369c42ae730d", "scanner": "scanner-primary", "fingerprint": "684f0e83ba7e1558", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dde3adb27bf7eebe", "level": "note", "message": {"text": "Unused endpoint: USE /api"}, "properties": {"repobilityId": "3a91ca4226b65696", "scanner": "scanner-primary", "fingerprint": "dde3adb27bf7eebe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a30e62ec3c8a210", "level": "note", "message": {"text": "Unused endpoint: USE /rest"}, "properties": {"repobilityId": "3857bedb7ca299cf", "scanner": "scanner-primary", "fingerprint": "7a30e62ec3c8a210", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a3f49a1ffbf734e7", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/upload"}, "properties": {"repobilityId": "97fbe338e0361532", "scanner": "scanner-primary", "fingerprint": "a3f49a1ffbf734e7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d0ecc923bfaed2b1", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/backup"}, "properties": {"repobilityId": "e33a4752cfe62dc4", "scanner": "scanner-primary", "fingerprint": "d0ecc923bfaed2b1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-54cdeca5d3479794", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/torrents"}, "properties": {"repobilityId": "3709a5e4803450c0", "scanner": "scanner-primary", "fingerprint": "54cdeca5d3479794", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f8242ba07247d2f8", "level": "note", "message": {"text": "Unused endpoint: USE /api/payments"}, "properties": {"repobilityId": "e611ac042ec3b189", "scanner": "scanner-primary", "fingerprint": "f8242ba07247d2f8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f22cf013c13a7f0c", "level": "note", "message": {"text": "Unused endpoint: GET /sw.js"}, "properties": {"repobilityId": "4f9e776f64fe5ea3", "scanner": "scanner-primary", "fingerprint": "f22cf013c13a7f0c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5881fad21d09723d", "level": "note", "message": {"text": "Unused endpoint: GET /manifest.json"}, "properties": {"repobilityId": "35dc01b98cff899e", "scanner": "scanner-primary", "fingerprint": "5881fad21d09723d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f02a079c69b52f2d", "level": "note", "message": {"text": "Unused endpoint: USE /"}, "properties": {"repobilityId": "08149df5f9161616", "scanner": "scanner-primary", "fingerprint": "f02a079c69b52f2d", "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": "f3ac30128fbadf4c", "scanner": "scanner-primary", "fingerprint": "6eb452fbfb454d20", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d93a530ce10d47d9", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin"}, "properties": {"repobilityId": "d6476c4f0be03d3e", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ed41dcda9412cd76", "level": "note", "message": {"text": "Unused endpoint: USE /api/catalog"}, "properties": {"repobilityId": "a022d6c25fdd9d14", "scanner": "scanner-primary", "fingerprint": "ed41dcda9412cd76", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d54d8e574b4d6eaf", "level": "note", "message": {"text": "Unused endpoint: USE /api/artists"}, "properties": {"repobilityId": "ece83da74ba9a446", "scanner": "scanner-primary", "fingerprint": "d54d8e574b4d6eaf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c634cbb07d397313", "level": "note", "message": {"text": "Unused endpoint: USE /api/albums"}, "properties": {"repobilityId": "49d74d94427bbfec", "scanner": "scanner-primary", "fingerprint": "c634cbb07d397313", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7596981f9ee52e11", "level": "note", "message": {"text": "Unused endpoint: USE /api/tracks"}, "properties": {"repobilityId": "1d01dd4236111412", "scanner": "scanner-primary", "fingerprint": "7596981f9ee52e11", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4f40b23feb6761c0", "level": "note", "message": {"text": "Unused endpoint: USE /api/dig"}, "properties": {"repobilityId": "25d277f0f6390503", "scanner": "scanner-primary", "fingerprint": "4f40b23feb6761c0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-927d00be000e74bc", "level": "note", "message": {"text": "Unused endpoint: USE /api/playlists"}, "properties": {"repobilityId": "70c3ecf87b878c31", "scanner": "scanner-primary", "fingerprint": "927d00be000e74bc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d73ccf163920bd14", "level": "note", "message": {"text": "Unused endpoint: USE /api/storage"}, "properties": {"repobilityId": "0b359cf58f71a827", "scanner": "scanner-primary", "fingerprint": "d73ccf163920bd14", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6651c957f9f6894c", "level": "note", "message": {"text": "Unused endpoint: USE /api/import"}, "properties": {"repobilityId": "bd9eec3223f92239", "scanner": "scanner-primary", "fingerprint": "6651c957f9f6894c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-84e9aca0a013554f", "level": "note", "message": {"text": "Unused endpoint: USE /api/releases"}, "properties": {"repobilityId": "1f56a1f1459dbd49", "scanner": "scanner-primary", "fingerprint": "84e9aca0a013554f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e332c50fd5e64865", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/releases"}, "properties": {"repobilityId": "8250230772f5f1d0", "scanner": "scanner-primary", "fingerprint": "e332c50fd5e64865", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-06c88a2e2dc65557", "level": "note", "message": {"text": "Unused endpoint: USE /api/stats"}, "properties": {"repobilityId": "87392c38cf3db0c3", "scanner": "scanner-primary", "fingerprint": "06c88a2e2dc65557", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e15049a37be53111", "level": "note", "message": {"text": "Unused endpoint: USE /api/stats/library"}, "properties": {"repobilityId": "3962f4ecb4b58ef7", "scanner": "scanner-primary", "fingerprint": "e15049a37be53111", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d0f2ece6e65b9aac", "level": "note", "message": {"text": "Unused endpoint: USE /api/community"}, "properties": {"repobilityId": "0320135c55a4a61e", "scanner": "scanner-primary", "fingerprint": "d0f2ece6e65b9aac", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bcd27e2f0338f9af", "level": "note", "message": {"text": "Unused endpoint: USE /api/browser"}, "properties": {"repobilityId": "5c4abd9a75f82746", "scanner": "scanner-primary", "fingerprint": "bcd27e2f0338f9af", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ad0d4a22f4714fc", "level": "note", "message": {"text": "Unused endpoint: USE /api/metadata"}, "properties": {"repobilityId": "ce969598df517767", "scanner": "scanner-primary", "fingerprint": "0ad0d4a22f4714fc", "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": "0a94e7e791e6582e", "scanner": "scanner-primary", "fingerprint": "4ff40cb10f7c8519", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-af74116085195f95", "level": "note", "message": {"text": "Unused endpoint: USE /api/comments"}, "properties": {"repobilityId": "06216ba1c240bce9", "scanner": "scanner-primary", "fingerprint": "af74116085195f95", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2b92dc87a4256298", "level": "note", "message": {"text": "Unused endpoint: USE /api/chat"}, "properties": {"repobilityId": "f83edb73ef3cd8ea", "scanner": "scanner-primary", "fingerprint": "2b92dc87a4256298", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-053617d8147f9976", "level": "note", "message": {"text": "Unused endpoint: USE /api/live"}, "properties": {"repobilityId": "b22b0e0977101719", "scanner": "scanner-primary", "fingerprint": "053617d8147f9976", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-034e14696ec45017", "level": "note", "message": {"text": "Unused endpoint: USE /api/unlock"}, "properties": {"repobilityId": "61638e85078e8a8b", "scanner": "scanner-primary", "fingerprint": "034e14696ec45017", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-280808dae6d10af8", "level": "note", "message": {"text": "Unused endpoint: USE /api/lifecycle"}, "properties": {"repobilityId": "29ab883337660abb", "scanner": "scanner-primary", "fingerprint": "280808dae6d10af8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4264e1f5d1f42db6", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/lifecycle"}, "properties": {"repobilityId": "237bf450d713ee25", "scanner": "scanner-primary", "fingerprint": "4264e1f5d1f42db6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-686f627db3a6399d", "level": "note", "message": {"text": "Unused endpoint: USE /api/ap"}, "properties": {"repobilityId": "9f93f13e7dca8424", "scanner": "scanner-primary", "fingerprint": "686f627db3a6399d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b9ed50f6493a17dd", "level": "note", "message": {"text": "Unused endpoint: USE /api/proxy"}, "properties": {"repobilityId": "2ec5c9f892fcfc3c", "scanner": "scanner-primary", "fingerprint": "b9ed50f6493a17dd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-be6dd02442a453ee", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin/tasks"}, "properties": {"repobilityId": "d699977a060bf8d4", "scanner": "scanner-primary", "fingerprint": "be6dd02442a453ee", "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": "a28b8fb2d1c1aa8c", "scanner": "scanner-primary", "fingerprint": "a74449cc5d561bad", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6b86b877fdc57c6f", "level": "note", "message": {"text": "Unused endpoint: GET /share/:id"}, "properties": {"repobilityId": "2ba23e48897c0111", "scanner": "scanner-primary", "fingerprint": "6b86b877fdc57c6f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3f08df1c2c3eef64", "level": "note", "message": {"text": "Unused endpoint: POST /submit-listens"}, "properties": {"repobilityId": "114cf2f3099fb68c", "scanner": "scanner-primary", "fingerprint": "3f08df1c2c3eef64", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-512ccb0fd0b230ba", "level": "note", "message": {"text": "Unused endpoint: GET /settings"}, "properties": {"repobilityId": "fa8173b754927b6f", "scanner": "scanner-primary", "fingerprint": "512ccb0fd0b230ba", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e9fcb61155d56f2f", "level": "note", "message": {"text": "Unused endpoint: GET /genres"}, "properties": {"repobilityId": "995774c744ff1653", "scanner": "scanner-primary", "fingerprint": "e9fcb61155d56f2f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d16e4fa529c520e9", "level": "note", "message": {"text": "Unused endpoint: GET /search"}, "properties": {"repobilityId": "ca855c197c3dc37c", "scanner": "scanner-primary", "fingerprint": "d16e4fa529c520e9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0cf9438c240e8830", "level": "note", "message": {"text": "Unused endpoint: GET /recommendations/:id"}, "properties": {"repobilityId": "1ef30f63eb34e83b", "scanner": "scanner-primary", "fingerprint": "0cf9438c240e8830", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e8b3ede8a71f9528", "level": "note", "message": {"text": "Unused endpoint: GET /tracks/:id/related"}, "properties": {"repobilityId": "74f53245a4014437", "scanner": "scanner-primary", "fingerprint": "e8b3ede8a71f9528", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-314ed0887376003a", "level": "note", "message": {"text": "Unused endpoint: GET /random"}, "properties": {"repobilityId": "68ae61d5300c31b6", "scanner": "scanner-primary", "fingerprint": "314ed0887376003a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5baa8971ebe192a1", "level": "note", "message": {"text": "Unused endpoint: GET /"}, "properties": {"repobilityId": "f06331c418e9c02a", "scanner": "scanner-primary", "fingerprint": "5baa8971ebe192a1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e7cd423e638f78f", "level": "note", "message": {"text": "Unused endpoint: GET /starred"}, "properties": {"repobilityId": "a15621a8addc8bf4", "scanner": "scanner-primary", "fingerprint": "8e7cd423e638f78f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0cb8c758943568de", "level": "note", "message": {"text": "Unused endpoint: GET /pricing/batch"}, "properties": {"repobilityId": "579ef9d362bf92d3", "scanner": "scanner-primary", "fingerprint": "0cb8c758943568de", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a009b1a56794f45", "level": "note", "message": {"text": "Unused endpoint: POST /"}, "properties": {"repobilityId": "4f38fcb966ec33f6", "scanner": "scanner-primary", "fingerprint": "7a009b1a56794f45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}