{"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-6157d501022dd5b7", "name": "Stray `console.log` in TS/JS \u2014 server/server.js:1412", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/server.js:1412"}, "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-6864b3ecb475a37b", "name": "Stray `console.log` in TS/JS \u2014 server/scripts/decrypt-all-messages.js:75", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/scripts/decrypt-all-messages.js:75"}, "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-5468ac17905b4d02", "name": "Stray `console.log` in TS/JS \u2014 server/lib/composio.js:91", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/composio.js:91"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1a4c123435072a43", "name": "Stray `console.log` in TS/JS \u2014 server/lib/codegen.js:27", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/codegen.js:27"}, "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-7946123e89c8cf23", "name": "Stray `console.log` in TS/JS \u2014 server/lib/suno.js:103", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/suno.js:103"}, "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-73e2cf6de9c314ca", "name": "Stray `console.log` in TS/JS \u2014 server/lib/db.js:302", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/db.js:302"}, "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-a466fc3793092d59", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ManualModelSelector.jsx:61", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ManualModelSelector.jsx:61"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2c389b05764fa7b3", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/BrandPills.jsx:232", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/BrandPills.jsx:232"}, "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-189dac16e4a35a50", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/MessageRenderer.jsx:111", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/MessageRenderer.jsx:111"}, "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-c756d99653e1e977", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ApiKeysPage.jsx:350", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ApiKeysPage.jsx:350"}, "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-bc64c2bb03f19db4", "name": "Stray `console.log` in TS/JS \u2014 client/src/components/ApiKeysPage.jsx:40", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 client/src/components/ApiKeysPage.jsx: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-ca84d560da186454", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/LandingPage.jsx:128", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/LandingPage.jsx:128"}, "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-5f0455b7ea45e0f8", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ArtistStudio.jsx:122", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ArtistStudio.jsx:122"}, "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-557c9d263c46c7f2", "name": "\"active\" state uses light bg in a dark theme \u2014 client/src/components/ArtistStudio.jsx:54", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 client/src/components/ArtistStudio.jsx:54"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8dd33648fb3b7f96", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/Pricing.jsx:301", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/Pricing.jsx:301"}, "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-2b164b56bc5f7b2c", "name": "Icon-only button without accessible name \u2014 client/src/components/AgentsPage.jsx:310", "shortDescription": {"text": "Icon-only button without accessible name \u2014 client/src/components/AgentsPage.jsx:310"}, "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-503436eb19ab85d1", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/AgentsPage.jsx:199", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/AgentsPage.jsx:199"}, "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-868dfe1081a136e1", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ArtifactViewer.jsx:406", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ArtifactViewer.jsx:406"}, "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-34852c7f636a62ed", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ArtifactViewer.jsx:95", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ArtifactViewer.jsx:95"}, "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-57de4985e7d119d9", "name": "Icon-only button without accessible name \u2014 client/src/components/DebateSetup.jsx:86", "shortDescription": {"text": "Icon-only button without accessible name \u2014 client/src/components/DebateSetup.jsx:86"}, "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-67bebff34f39e31d", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/DebateSetup.jsx:119", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/DebateSetup.jsx:119"}, "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-af520e5fa723401e", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ModelPreferencesPage.jsx:153", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ModelPreferencesPage.jsx:153"}, "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-094631b6255bc0ff", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ModelPreferencesPage.jsx:102", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ModelPreferencesPage.jsx:102"}, "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-8ab88abc1e8df933", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/MemoryPage.jsx:103", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/MemoryPage.jsx:103"}, "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-8f585e42a8f1f394", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/CodeStudio.jsx:395", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/CodeStudio.jsx:395"}, "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-01a14a7dd8898496", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/Navbar.jsx:100", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/Navbar.jsx:100"}, "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-fe710237e45dcdec", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ChatMessage.jsx:129", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ChatMessage.jsx: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-4748c2389376ade7", "name": "Icon-only button without accessible name \u2014 client/src/components/ParallelPicker.jsx:73", "shortDescription": {"text": "Icon-only button without accessible name \u2014 client/src/components/ParallelPicker.jsx:73"}, "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-b93c8fbc0da5fb5b", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ParallelPicker.jsx:140", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ParallelPicker.jsx: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-877fab6982096551", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/Composer.jsx:155", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/Composer.jsx:155"}, "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-5102ea79d855bc4c", "name": "Icon-only button without accessible name \u2014 client/src/components/ProjectSettingsModal.jsx:85", "shortDescription": {"text": "Icon-only button without accessible name \u2014 client/src/components/ProjectSettingsModal.jsx:85"}, "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-641494e1b56a851b", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/MusicComposer.jsx:355", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/MusicComposer.jsx:355"}, "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-6fe0c5b88bcd4d5a", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ProjectsSidebar.jsx:132", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ProjectsSidebar.jsx:132"}, "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-e6ed1d9be4c1f942", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ProjectsSidebar.jsx:102", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ProjectsSidebar.jsx:102"}, "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-412bd79db0b56e71", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/IntegrationsPage.jsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/IntegrationsPage.jsx:131"}, "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-a5428ae5ec72d8fd", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/UsagePage.jsx:234", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/UsagePage.jsx:234"}, "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-e26072f03c0a8433", "name": "Icon-only button without accessible name \u2014 client/src/pages/ChatPage.jsx:961", "shortDescription": {"text": "Icon-only button without accessible name \u2014 client/src/pages/ChatPage.jsx:961"}, "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-cf84ac684fd3a64c", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/ChatPage.jsx:584", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/ChatPage.jsx:584"}, "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-a1a7bdde1aea8ac5", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/pages/OurModelRoute.jsx:103", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/pages/OurModelRoute.jsx:103"}, "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-a5d6d2b03c09016d", "name": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/IntroRoute.jsx:395", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/IntroRoute.jsx:395"}, "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-3f22b7665648d69a", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/pages/IntroRoute.jsx:372", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/pages/IntroRoute.jsx:372"}, "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-860ca59d0d1b7553", "name": "Runtime dotenv file present in repo: client/.env.production", "shortDescription": {"text": "Runtime dotenv file present in repo: client/.env.production"}, "fullDescription": {"text": "`client/.env.production` looks like a runtime dotenv file. No high-confidence secret value was matched, but runtime dotenv files often drift into live credentials. Move real values to a secret manager and keep only `.env.example` style templates in source control."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-73b33fe78d5eb8d9", "name": "Possible secret in ia.py", "shortDescription": {"text": "Possible secret in ia.py"}, "fullDescription": {"text": "Detected pattern matching generic_api_key. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-0f8f082277d2283d", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/MessageRenderer.jsx:111", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/MessageRenderer.jsx:111"}, "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-dcc10fa5807006ff", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/LandingPage.jsx:128", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/LandingPage.jsx:128"}, "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-998754fd88a835da", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/Pricing.jsx:301", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/Pricing.jsx:301"}, "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-4ed37059c1176b3b", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ArtifactViewer.jsx:95", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ArtifactViewer.jsx:95"}, "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-f7d9ac020d02ac48", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ModelPreferencesPage.jsx:102", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ModelPreferencesPage.jsx:102"}, "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-2712a232879c58be", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/MemoryPage.jsx:103", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/MemoryPage.jsx:103"}, "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-80609ffa25eff665", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ProjectsSidebar.jsx:102", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ProjectsSidebar.jsx:102"}, "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-536324626fc8cbdd", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/pages/OurModelRoute.jsx:103", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/pages/OurModelRoute.jsx:103"}, "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-b3b9e7c13d73ffbd", "name": "Insecure pattern 'dangerous_innerhtml' in client/src/pages/IntroRoute.jsx:372", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/pages/IntroRoute.jsx:372"}, "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-17546b5e1ac7041f", "name": "Insecure pattern 'local_storage_auth_token' in client/src/lib/api.js:10", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in client/src/lib/api.js:10"}, "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-a1996ad8e8562d38", "name": "Insecure pattern 'new_function_used' in client/src/lib/pptxBuilder.js:57", "shortDescription": {"text": "Insecure pattern 'new_function_used' in client/src/lib/pptxBuilder.js:57"}, "fullDescription": {"text": "Found a known-risky pattern (new_function_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-90fcb44d9b461505", "name": "Possible secret in .claude/settings.local.json", "shortDescription": {"text": "Possible secret in .claude/settings.local.json"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-104478511f6c4c9e", "name": "Very large file: server/server.js (2222 lines)", "shortDescription": {"text": "Very large file: server/server.js (2222 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 104 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 42 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 45 placeholder/mock markers across 15 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci, tests. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-505bc666a82f9849", "name": "Agent instruction/config may expose a secret: .claude/settings.local.json", "shortDescription": {"text": "Agent instruction/config may expose a secret: .claude/settings.local.json"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-26dac11499639da7", "name": "Commented-code block (6 lines) in server/server.js:1499", "shortDescription": {"text": "Commented-code block (6 lines) in server/server.js:1499"}, "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-9b4abeae20a479cc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/server.js:1868", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/server.js:1868"}, "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-d71d174be7cfa364", "name": "Commented-code block (5 lines) in server/lib/sourceScoring.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in server/lib/sourceScoring.js:1"}, "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-dd2b206b6149df3f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/openrouter.js:42", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/openrouter.js:42"}, "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-cb2fb44b064e5d58", "name": "Commented-code block (5 lines) in server/lib/skills.js:27", "shortDescription": {"text": "Commented-code block (5 lines) in server/lib/skills.js:27"}, "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-db4f66b65f7f9b4b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/paypal.js:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/paypal.js:20"}, "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-b5a1a18aee7576db", "name": "Commented-code block (5 lines) in server/lib/deepSearch.js:233", "shortDescription": {"text": "Commented-code block (5 lines) in server/lib/deepSearch.js:233"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5f8512a37067d6a9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/router.js:66", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/router.js:66"}, "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-4f690d24156a51a6", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/v1.js:89", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/v1.js:89"}, "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-bb7655dc8fd037d4", "name": "Commented-code block (5 lines) in client/src/hooks/useHistory.js:113", "shortDescription": {"text": "Commented-code block (5 lines) in client/src/hooks/useHistory.js:113"}, "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-17733f2e2c049be5", "name": "Commented-code block (5 lines) in client/src/components/MessageRenderer.jsx:19", "shortDescription": {"text": "Commented-code block (5 lines) in client/src/components/MessageRenderer.jsx:19"}, "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-46aca039f78e822c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/api.js:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/api.js:38"}, "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-e8a7843dd74d6309", "name": "Commented-code block (13 lines) in client/src/lib/pptxBuilder.js:7", "shortDescription": {"text": "Commented-code block (13 lines) in client/src/lib/pptxBuilder.js:7"}, "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-084f6b133656cbe3", "name": "Commented-code block (5 lines) in client/src/lib/brands.js:1", "shortDescription": {"text": "Commented-code block (5 lines) in client/src/lib/brands.js:1"}, "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-b0b5e7cb1208a7cd", "name": "13 env vars used in code but missing from .env.example", "shortDescription": {"text": "13 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `COMPOSIO_API_KEY`, `DELT_INFERENCE_KEY`, `DELT_INFERENCE_URL`, `ENCRYPT_CONVERSATIONS`, `FAL_API_KEY`, `MESSAGE_ENCRYPTION_KEY`, `NODE_TLS_REJECT_UNAUTHORIZED`, `PAYPAL_MODE` + 5 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-b5c3c5ae9af7d45e", "name": "Frontend route `/thanks` has no Link/navigate to it \u2014 client/src/App.jsx", "shortDescription": {"text": "Frontend route `/thanks` has no Link/navigate to it \u2014 client/src/App.jsx"}, "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-3bea4a2ca9e9c2ad", "name": "Frontend route `/goodbye` has no Link/navigate to it \u2014 client/src/App.jsx", "shortDescription": {"text": "Frontend route `/goodbye` has no Link/navigate to it \u2014 client/src/App.jsx"}, "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-5af0937f7090be2c", "name": "Frontend route `/subscribe/success` has no Link/navigate to it \u2014 client/src/App.jsx", "shortDescription": {"text": "Frontend route `/subscribe/success` has no Link/navigate to it \u2014 client/src/App.jsx"}, "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-5f804b9c3b7fa4bb", "name": "Frontend route `/privacy-settings` has no Link/navigate to it \u2014 client/src/App.jsx", "shortDescription": {"text": "Frontend route `/privacy-settings` has no Link/navigate to it \u2014 client/src/App.jsx"}, "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-956c2bf78ad86288", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (server/server.js:1868)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (server/server.js:1868)"}, "fullDescription": {"text": "`server/server.js:1868` 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-6a36ca0de71b7fe9", "name": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (server/routes/v1.js:89)", "shortDescription": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (server/routes/v1.js:89)"}, "fullDescription": {"text": "`server/routes/v1.js:89` 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-383cdb7fe9cebb9d", "name": "Unused endpoint: POST /api/auth/google", "shortDescription": {"text": "Unused endpoint: POST /api/auth/google"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/auth/google` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a5b3437e64c8f7b4", "name": "Unused endpoint: POST /api/auth/register", "shortDescription": {"text": "Unused endpoint: POST /api/auth/register"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/auth/register` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fd55aa0818a7c897", "name": "Unused endpoint: POST /api/auth/login", "shortDescription": {"text": "Unused endpoint: POST /api/auth/login"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/auth/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ee4aa5ddab88c9dc", "name": "Unused endpoint: GET /api/auth/me", "shortDescription": {"text": "Unused endpoint: GET /api/auth/me"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/auth/me` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3b94923f366fed0e", "name": "Unused endpoint: GET /api/projects", "shortDescription": {"text": "Unused endpoint: GET /api/projects"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/projects` 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-9ecbca60df3adf4c", "name": "Unused endpoint: GET /api/projects/:id", "shortDescription": {"text": "Unused endpoint: GET /api/projects/:id"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/projects/: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-16a480533217943d", "name": "Unused endpoint: POST /api/projects", "shortDescription": {"text": "Unused endpoint: POST /api/projects"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/projects` 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-3f4a46c6d6faaa73", "name": "Unused endpoint: PUT /api/projects/:id", "shortDescription": {"text": "Unused endpoint: PUT /api/projects/:id"}, "fullDescription": {"text": "`server/server.js` declares `PUT /api/projects/: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-1ec3273d14ad0424", "name": "Unused endpoint: DELETE /api/projects/:id", "shortDescription": {"text": "Unused endpoint: DELETE /api/projects/:id"}, "fullDescription": {"text": "`server/server.js` declares `DELETE /api/projects/: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-290013142a37490b", "name": "Unused endpoint: PUT /api/conversations/:id/project", "shortDescription": {"text": "Unused endpoint: PUT /api/conversations/:id/project"}, "fullDescription": {"text": "`server/server.js` declares `PUT /api/conversations/:id/project` 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-c4b0361ac0f5eeb9", "name": "Unused endpoint: GET /api/agents", "shortDescription": {"text": "Unused endpoint: GET /api/agents"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/agents` 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-d8dc21709e9d79c6", "name": "Unused endpoint: GET /api/agents/:id", "shortDescription": {"text": "Unused endpoint: GET /api/agents/:id"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/agents/: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-ab31d7e480a710b2", "name": "Unused endpoint: POST /api/agents", "shortDescription": {"text": "Unused endpoint: POST /api/agents"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/agents` 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-b405f19b320d99ed", "name": "Unused endpoint: PUT /api/agents/:id", "shortDescription": {"text": "Unused endpoint: PUT /api/agents/:id"}, "fullDescription": {"text": "`server/server.js` declares `PUT /api/agents/: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-4f288126896fe12d", "name": "Unused endpoint: DELETE /api/agents/:id", "shortDescription": {"text": "Unused endpoint: DELETE /api/agents/:id"}, "fullDescription": {"text": "`server/server.js` declares `DELETE /api/agents/: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-a74464b0f1216462", "name": "Unused endpoint: GET /api/memory", "shortDescription": {"text": "Unused endpoint: GET /api/memory"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/memory` 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-3a1c5c579cf2cd4d", "name": "Unused endpoint: PUT /api/memory", "shortDescription": {"text": "Unused endpoint: PUT /api/memory"}, "fullDescription": {"text": "`server/server.js` declares `PUT /api/memory` 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-86c89e97ef3b57ac", "name": "Unused endpoint: GET /api/preferences/models", "shortDescription": {"text": "Unused endpoint: GET /api/preferences/models"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/preferences/models` 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-674b816fbdd8ff26", "name": "Unused endpoint: PUT /api/preferences/models", "shortDescription": {"text": "Unused endpoint: PUT /api/preferences/models"}, "fullDescription": {"text": "`server/server.js` declares `PUT /api/preferences/models` 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-0470e8eced199dda", "name": "Unused endpoint: GET /api/privacy/export", "shortDescription": {"text": "Unused endpoint: GET /api/privacy/export"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/privacy/export` 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-86cb49ad502909f1", "name": "Unused endpoint: DELETE /api/privacy/account", "shortDescription": {"text": "Unused endpoint: DELETE /api/privacy/account"}, "fullDescription": {"text": "`server/server.js` declares `DELETE /api/privacy/account` 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-2e3780dcba194f52", "name": "Unused endpoint: POST /api/chat/debate", "shortDescription": {"text": "Unused endpoint: POST /api/chat/debate"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/chat/debate` 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-8724497fdb00ccd3", "name": "Unused endpoint: POST /api/chat/merge", "shortDescription": {"text": "Unused endpoint: POST /api/chat/merge"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/chat/merge` 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-60e78a867a1a28c9", "name": "Unused endpoint: GET /api/usage", "shortDescription": {"text": "Unused endpoint: GET /api/usage"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/usage` 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-55890047a9ea2bbe", "name": "Unused endpoint: GET /api/quota", "shortDescription": {"text": "Unused endpoint: GET /api/quota"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/quota` 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-32e9ac37a764cea0", "name": "Unused endpoint: POST /api/credits/transfer", "shortDescription": {"text": "Unused endpoint: POST /api/credits/transfer"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/credits/transfer` 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-e9c21c7292ee8388", "name": "Unused endpoint: GET /api/catalog", "shortDescription": {"text": "Unused endpoint: GET /api/catalog"}, "fullDescription": {"text": "`server/server.js` declares `GET /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-c921d242ce55dba1", "name": "Unused endpoint: GET /api/conversations", "shortDescription": {"text": "Unused endpoint: GET /api/conversations"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/conversations` 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-4045c741ef650832", "name": "Unused endpoint: GET /api/conversations/:id", "shortDescription": {"text": "Unused endpoint: GET /api/conversations/:id"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/conversations/: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-24a206bd919f2f73", "name": "Unused endpoint: PUT /api/conversations/:id", "shortDescription": {"text": "Unused endpoint: PUT /api/conversations/:id"}, "fullDescription": {"text": "`server/server.js` declares `PUT /api/conversations/: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-81406ff09b73ded6", "name": "Unused endpoint: DELETE /api/conversations/:id", "shortDescription": {"text": "Unused endpoint: DELETE /api/conversations/:id"}, "fullDescription": {"text": "`server/server.js` declares `DELETE /api/conversations/: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-7c8982ec1329029f", "name": "Unused endpoint: POST /api/code/session", "shortDescription": {"text": "Unused endpoint: POST /api/code/session"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/code/session` 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-e89c3b030562126b", "name": "Unused endpoint: POST /api/code/session/:id/edit", "shortDescription": {"text": "Unused endpoint: POST /api/code/session/:id/edit"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/code/session/:id/edit` 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-d44890fa4b665db7", "name": "Unused endpoint: GET /api/code/session/:id.zip", "shortDescription": {"text": "Unused endpoint: GET /api/code/session/:id.zip"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/code/session/:id.zip` 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-0460984524eae5cf", "name": "Unused endpoint: GET /api/code/session/:id/preview/*", "shortDescription": {"text": "Unused endpoint: GET /api/code/session/:id/preview/*"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/code/session/:id/preview/*` 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-24d819daa2be5852", "name": "Unused endpoint: POST /api/route", "shortDescription": {"text": "Unused endpoint: POST /api/route"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/route` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-72d08b913b763566", "name": "Unused endpoint: POST /api/deep-search", "shortDescription": {"text": "Unused endpoint: POST /api/deep-search"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/deep-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-88f89a9326454f53", "name": "Unused endpoint: POST /api/age-verify", "shortDescription": {"text": "Unused endpoint: POST /api/age-verify"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/age-verify` 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-9d2517f9eafc5297", "name": "Unused endpoint: POST /api/chat", "shortDescription": {"text": "Unused endpoint: POST /api/chat"}, "fullDescription": {"text": "`server/server.js` declares `POST /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-a8d6210d067faf8c", "name": "Unused endpoint: POST /api/chat/stream", "shortDescription": {"text": "Unused endpoint: POST /api/chat/stream"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/chat/stream` 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-21ffafbe996c5c91", "name": "Unused endpoint: POST /api/subscribe/activate", "shortDescription": {"text": "Unused endpoint: POST /api/subscribe/activate"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/subscribe/activate` 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-d5d1aebd0d8c8397", "name": "Unused endpoint: GET /api/subscribe/confirm", "shortDescription": {"text": "Unused endpoint: GET /api/subscribe/confirm"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/subscribe/confirm` 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-9721a8bd8c654afb", "name": "Unused endpoint: POST /api/subscribe/:plan", "shortDescription": {"text": "Unused endpoint: POST /api/subscribe/:plan"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/subscribe/:plan` 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-1192affce0fb004d", "name": "Unused endpoint: GET /api/paypal/config", "shortDescription": {"text": "Unused endpoint: GET /api/paypal/config"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/paypal/config` 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-2d5c1d8d8ab2d64a", "name": "Unused endpoint: GET /api/credits/packs", "shortDescription": {"text": "Unused endpoint: GET /api/credits/packs"}, "fullDescription": {"text": "`server/server.js` declares `GET /api/credits/packs` 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-70a3c1b41971d632", "name": "Unused endpoint: POST /api/credits/order", "shortDescription": {"text": "Unused endpoint: POST /api/credits/order"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/credits/order` 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-79d2a3b096c241e9", "name": "Unused endpoint: POST /api/credits/capture", "shortDescription": {"text": "Unused endpoint: POST /api/credits/capture"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/credits/capture` 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-17805c102de7651c", "name": "Unused endpoint: POST /api/paypal/webhook", "shortDescription": {"text": "Unused endpoint: POST /api/paypal/webhook"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/paypal/webhook` 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-b392093947d3e664", "name": "Unused endpoint: POST /api/image", "shortDescription": {"text": "Unused endpoint: POST /api/image"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/image` 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-536fc60d1287e634", "name": "Unused endpoint: POST /api/upload", "shortDescription": {"text": "Unused endpoint: POST /api/upload"}, "fullDescription": {"text": "`server/server.js` declares `POST /api/upload` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/24862"}, "properties": {"repository": "cecileglehen/BACKEND", "repoUrl": "https://github.com/cecileglehen/BACKEND", "branch": "main"}, "results": [{"ruleId": "scanner-6157d501022dd5b7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/server.js:1412"}, "properties": {"repobilityId": "72b828fc11274423", "scanner": "scanner-primary", "fingerprint": "6157d501022dd5b7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6864b3ecb475a37b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/scripts/decrypt-all-messages.js:75"}, "properties": {"repobilityId": "f3380ba91fead872", "scanner": "scanner-primary", "fingerprint": "6864b3ecb475a37b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5468ac17905b4d02", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/composio.js:91"}, "properties": {"repobilityId": "d3f209cf3903f1f0", "scanner": "scanner-primary", "fingerprint": "5468ac17905b4d02", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1a4c123435072a43", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/codegen.js:27"}, "properties": {"repobilityId": "0058df6d58e83270", "scanner": "scanner-primary", "fingerprint": "1a4c123435072a43", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7946123e89c8cf23", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/suno.js:103"}, "properties": {"repobilityId": "cb3729316892300e", "scanner": "scanner-primary", "fingerprint": "7946123e89c8cf23", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-73e2cf6de9c314ca", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server/lib/db.js:302"}, "properties": {"repobilityId": "650cc47b60999144", "scanner": "scanner-primary", "fingerprint": "73e2cf6de9c314ca", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a466fc3793092d59", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ManualModelSelector.jsx:61"}, "properties": {"repobilityId": "d746400b1f577eca", "scanner": "scanner-primary", "fingerprint": "a466fc3793092d59", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2c389b05764fa7b3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/BrandPills.jsx:232"}, "properties": {"repobilityId": "003c1d78af997d40", "scanner": "scanner-primary", "fingerprint": "2c389b05764fa7b3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-189dac16e4a35a50", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/MessageRenderer.jsx:111"}, "properties": {"repobilityId": "752ba35e252abc8d", "scanner": "scanner-primary", "fingerprint": "189dac16e4a35a50", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-c756d99653e1e977", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ApiKeysPage.jsx:350"}, "properties": {"repobilityId": "08f89874f6aca8e1", "scanner": "scanner-primary", "fingerprint": "c756d99653e1e977", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bc64c2bb03f19db4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 client/src/components/ApiKeysPage.jsx:40"}, "properties": {"repobilityId": "f4c3294a60b6fb0b", "scanner": "scanner-primary", "fingerprint": "bc64c2bb03f19db4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ca84d560da186454", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/LandingPage.jsx:128"}, "properties": {"repobilityId": "4d68ba8e2913d66d", "scanner": "scanner-primary", "fingerprint": "ca84d560da186454", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-5f0455b7ea45e0f8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ArtistStudio.jsx:122"}, "properties": {"repobilityId": "757cb80e205d5884", "scanner": "scanner-primary", "fingerprint": "5f0455b7ea45e0f8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-557c9d263c46c7f2", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 client/src/components/ArtistStudio.jsx:54"}, "properties": {"repobilityId": "3da8d85653769151", "scanner": "scanner-primary", "fingerprint": "557c9d263c46c7f2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-8dd33648fb3b7f96", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/Pricing.jsx:301"}, "properties": {"repobilityId": "dd6a1b9ccb0568c0", "scanner": "scanner-primary", "fingerprint": "8dd33648fb3b7f96", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-2b164b56bc5f7b2c", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 client/src/components/AgentsPage.jsx:310"}, "properties": {"repobilityId": "55ad5da2280769ef", "scanner": "scanner-primary", "fingerprint": "2b164b56bc5f7b2c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-503436eb19ab85d1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/AgentsPage.jsx:199"}, "properties": {"repobilityId": "a2557405638e04b4", "scanner": "scanner-primary", "fingerprint": "503436eb19ab85d1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-868dfe1081a136e1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ArtifactViewer.jsx:406"}, "properties": {"repobilityId": "841ae69395722555", "scanner": "scanner-primary", "fingerprint": "868dfe1081a136e1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-34852c7f636a62ed", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ArtifactViewer.jsx:95"}, "properties": {"repobilityId": "7a31b24d727fb724", "scanner": "scanner-primary", "fingerprint": "34852c7f636a62ed", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-57de4985e7d119d9", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 client/src/components/DebateSetup.jsx:86"}, "properties": {"repobilityId": "60ad261a252b358e", "scanner": "scanner-primary", "fingerprint": "57de4985e7d119d9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-67bebff34f39e31d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/DebateSetup.jsx:119"}, "properties": {"repobilityId": "1fc9980225e4773f", "scanner": "scanner-primary", "fingerprint": "67bebff34f39e31d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-af520e5fa723401e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ModelPreferencesPage.jsx:153"}, "properties": {"repobilityId": "52d7584e6aeb3b76", "scanner": "scanner-primary", "fingerprint": "af520e5fa723401e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-094631b6255bc0ff", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ModelPreferencesPage.jsx:102"}, "properties": {"repobilityId": "0c5fc32bf941b7d2", "scanner": "scanner-primary", "fingerprint": "094631b6255bc0ff", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-8ab88abc1e8df933", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/MemoryPage.jsx:103"}, "properties": {"repobilityId": "98f6121c5ed16ffb", "scanner": "scanner-primary", "fingerprint": "8ab88abc1e8df933", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-8f585e42a8f1f394", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/CodeStudio.jsx:395"}, "properties": {"repobilityId": "a19fc72660414e54", "scanner": "scanner-primary", "fingerprint": "8f585e42a8f1f394", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-01a14a7dd8898496", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/Navbar.jsx:100"}, "properties": {"repobilityId": "d161d1119686f6e7", "scanner": "scanner-primary", "fingerprint": "01a14a7dd8898496", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fe710237e45dcdec", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ChatMessage.jsx:129"}, "properties": {"repobilityId": "e39680463e6e6ec5", "scanner": "scanner-primary", "fingerprint": "fe710237e45dcdec", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4748c2389376ade7", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 client/src/components/ParallelPicker.jsx:73"}, "properties": {"repobilityId": "2869fddca0ea5695", "scanner": "scanner-primary", "fingerprint": "4748c2389376ade7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-b93c8fbc0da5fb5b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ParallelPicker.jsx:140"}, "properties": {"repobilityId": "24db4765ce31437b", "scanner": "scanner-primary", "fingerprint": "b93c8fbc0da5fb5b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-877fab6982096551", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/Composer.jsx:155"}, "properties": {"repobilityId": "406f11fc4bd2674e", "scanner": "scanner-primary", "fingerprint": "877fab6982096551", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5102ea79d855bc4c", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 client/src/components/ProjectSettingsModal.jsx:85"}, "properties": {"repobilityId": "e476540d4f8d68d0", "scanner": "scanner-primary", "fingerprint": "5102ea79d855bc4c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-641494e1b56a851b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/MusicComposer.jsx:355"}, "properties": {"repobilityId": "7d29a20ee0e1dd9b", "scanner": "scanner-primary", "fingerprint": "641494e1b56a851b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6fe0c5b88bcd4d5a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/ProjectsSidebar.jsx:132"}, "properties": {"repobilityId": "17df6163783c4c50", "scanner": "scanner-primary", "fingerprint": "6fe0c5b88bcd4d5a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e6ed1d9be4c1f942", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/components/ProjectsSidebar.jsx:102"}, "properties": {"repobilityId": "31b4e8828b8fac7d", "scanner": "scanner-primary", "fingerprint": "e6ed1d9be4c1f942", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-412bd79db0b56e71", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/IntegrationsPage.jsx:131"}, "properties": {"repobilityId": "29c6f72d90fda0c0", "scanner": "scanner-primary", "fingerprint": "412bd79db0b56e71", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a5428ae5ec72d8fd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/components/UsagePage.jsx:234"}, "properties": {"repobilityId": "f19db72c35438fbf", "scanner": "scanner-primary", "fingerprint": "a5428ae5ec72d8fd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e26072f03c0a8433", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 client/src/pages/ChatPage.jsx:961"}, "properties": {"repobilityId": "be38364b8c131c57", "scanner": "scanner-primary", "fingerprint": "e26072f03c0a8433", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-cf84ac684fd3a64c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/ChatPage.jsx:584"}, "properties": {"repobilityId": "cd4fe93268c9eb0b", "scanner": "scanner-primary", "fingerprint": "cf84ac684fd3a64c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a1a7bdde1aea8ac5", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/pages/OurModelRoute.jsx:103"}, "properties": {"repobilityId": "fb52e8be233f79c0", "scanner": "scanner-primary", "fingerprint": "a1a7bdde1aea8ac5", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-a5d6d2b03c09016d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 client/src/pages/IntroRoute.jsx:395"}, "properties": {"repobilityId": "e7c2aad58d780a17", "scanner": "scanner-primary", "fingerprint": "a5d6d2b03c09016d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3f22b7665648d69a", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 client/src/pages/IntroRoute.jsx:372"}, "properties": {"repobilityId": "78b733fba9262bec", "scanner": "scanner-primary", "fingerprint": "3f22b7665648d69a", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-860ca59d0d1b7553", "level": "error", "message": {"text": "Runtime dotenv file present in repo: client/.env.production"}, "properties": {"repobilityId": "ba10706fc4e1197b", "scanner": "scanner-primary", "fingerprint": "860ca59d0d1b7553", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["secrets", "config", "env-file", "runtime-env"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/.env.production"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-73b33fe78d5eb8d9", "level": "error", "message": {"text": "Possible secret in ia.py"}, "properties": {"repobilityId": "9519371d62d35166", "scanner": "scanner-primary", "fingerprint": "73b33fe78d5eb8d9", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "ia.py"}, "region": {"startLine": 4}}}]}, {"ruleId": "scanner-0f8f082277d2283d", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/MessageRenderer.jsx:111"}, "properties": {"repobilityId": "9d573334f2dd40fd", "scanner": "scanner-primary", "fingerprint": "0f8f082277d2283d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/MessageRenderer.jsx"}, "region": {"startLine": 111}}}]}, {"ruleId": "scanner-dcc10fa5807006ff", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/LandingPage.jsx:128"}, "properties": {"repobilityId": "acffc810a0629c6b", "scanner": "scanner-primary", "fingerprint": "dcc10fa5807006ff", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/LandingPage.jsx"}, "region": {"startLine": 128}}}]}, {"ruleId": "scanner-998754fd88a835da", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/Pricing.jsx:301"}, "properties": {"repobilityId": "1a1f5c646c355175", "scanner": "scanner-primary", "fingerprint": "998754fd88a835da", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/Pricing.jsx"}, "region": {"startLine": 301}}}]}, {"ruleId": "scanner-4ed37059c1176b3b", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ArtifactViewer.jsx:95"}, "properties": {"repobilityId": "dd12e998108fc3bd", "scanner": "scanner-primary", "fingerprint": "4ed37059c1176b3b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/ArtifactViewer.jsx"}, "region": {"startLine": 95}}}]}, {"ruleId": "scanner-f7d9ac020d02ac48", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ModelPreferencesPage.jsx:102"}, "properties": {"repobilityId": "cd00fc2004b55047", "scanner": "scanner-primary", "fingerprint": "f7d9ac020d02ac48", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/ModelPreferencesPage.jsx"}, "region": {"startLine": 102}}}]}, {"ruleId": "scanner-2712a232879c58be", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/MemoryPage.jsx:103"}, "properties": {"repobilityId": "88f4f9c87b1cc38f", "scanner": "scanner-primary", "fingerprint": "2712a232879c58be", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/MemoryPage.jsx"}, "region": {"startLine": 103}}}]}, {"ruleId": "scanner-80609ffa25eff665", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/components/ProjectsSidebar.jsx:102"}, "properties": {"repobilityId": "c9d4271abf450400", "scanner": "scanner-primary", "fingerprint": "80609ffa25eff665", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/components/ProjectsSidebar.jsx"}, "region": {"startLine": 102}}}]}, {"ruleId": "scanner-536324626fc8cbdd", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/pages/OurModelRoute.jsx:103"}, "properties": {"repobilityId": "d995df7bffb6febc", "scanner": "scanner-primary", "fingerprint": "536324626fc8cbdd", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/pages/OurModelRoute.jsx"}, "region": {"startLine": 103}}}]}, {"ruleId": "scanner-b3b9e7c13d73ffbd", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in client/src/pages/IntroRoute.jsx:372"}, "properties": {"repobilityId": "95a771e627586139", "scanner": "scanner-primary", "fingerprint": "b3b9e7c13d73ffbd", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/pages/IntroRoute.jsx"}, "region": {"startLine": 372}}}]}, {"ruleId": "scanner-17546b5e1ac7041f", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in client/src/lib/api.js:10"}, "properties": {"repobilityId": "4938a5ad9765c9f4", "scanner": "scanner-primary", "fingerprint": "17546b5e1ac7041f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/lib/api.js"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-a1996ad8e8562d38", "level": "error", "message": {"text": "Insecure pattern 'new_function_used' in client/src/lib/pptxBuilder.js:57"}, "properties": {"repobilityId": "021909de9f016acd", "scanner": "scanner-primary", "fingerprint": "a1996ad8e8562d38", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "new_function_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "client/src/lib/pptxBuilder.js"}, "region": {"startLine": 57}}}]}, {"ruleId": "scanner-90fcb44d9b461505", "level": "error", "message": {"text": "Possible secret in .claude/settings.local.json"}, "properties": {"repobilityId": "31609f8f1b78960c", "scanner": "scanner-primary", "fingerprint": "90fcb44d9b461505", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/settings.local.json"}, "region": {"startLine": 88}}}]}, {"ruleId": "scanner-104478511f6c4c9e", "level": "note", "message": {"text": "Very large file: server/server.js (2222 lines)"}, "properties": {"repobilityId": "d14264b8a00bed6d", "scanner": "scanner-primary", "fingerprint": "104478511f6c4c9e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "c697d5a4f3d04741", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "09d9e051c41eec60", "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": "d5645732d879f2cd", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "2d4898da992afd9f", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "971d001aad1354db", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "c6b4abcf5e706d77", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-505bc666a82f9849", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: .claude/settings.local.json"}, "properties": {"repobilityId": "777970b0fce0a93b", "scanner": "scanner-primary", "fingerprint": "505bc666a82f9849", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/settings.local.json"}, "region": {"startLine": 44}}}]}, {"ruleId": "scanner-26dac11499639da7", "level": "none", "message": {"text": "Commented-code block (6 lines) in server/server.js:1499"}, "properties": {"repobilityId": "6e85d372d445d8a2", "scanner": "scanner-primary", "fingerprint": "26dac11499639da7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9b4abeae20a479cc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/server.js:1868"}, "properties": {"repobilityId": "c03edc972c8b3345", "scanner": "scanner-primary", "fingerprint": "9b4abeae20a479cc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d71d174be7cfa364", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/lib/sourceScoring.js:1"}, "properties": {"repobilityId": "dd59626b6370937e", "scanner": "scanner-primary", "fingerprint": "d71d174be7cfa364", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dd2b206b6149df3f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/openrouter.js:42"}, "properties": {"repobilityId": "4c0e68144b84ea44", "scanner": "scanner-primary", "fingerprint": "dd2b206b6149df3f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cb2fb44b064e5d58", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/lib/skills.js:27"}, "properties": {"repobilityId": "3872a6d17688e97f", "scanner": "scanner-primary", "fingerprint": "cb2fb44b064e5d58", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-db4f66b65f7f9b4b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/paypal.js:20"}, "properties": {"repobilityId": "dc8a77a2217b04f0", "scanner": "scanner-primary", "fingerprint": "db4f66b65f7f9b4b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b5a1a18aee7576db", "level": "none", "message": {"text": "Commented-code block (5 lines) in server/lib/deepSearch.js:233"}, "properties": {"repobilityId": "5f650ee03197da78", "scanner": "scanner-primary", "fingerprint": "b5a1a18aee7576db", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5f8512a37067d6a9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/lib/router.js:66"}, "properties": {"repobilityId": "0b9e5610f31058c9", "scanner": "scanner-primary", "fingerprint": "5f8512a37067d6a9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4f690d24156a51a6", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server/routes/v1.js:89"}, "properties": {"repobilityId": "8781dabf140db3c0", "scanner": "scanner-primary", "fingerprint": "4f690d24156a51a6", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bb7655dc8fd037d4", "level": "none", "message": {"text": "Commented-code block (5 lines) in client/src/hooks/useHistory.js:113"}, "properties": {"repobilityId": "21c129f557aa8eb8", "scanner": "scanner-primary", "fingerprint": "bb7655dc8fd037d4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-17733f2e2c049be5", "level": "none", "message": {"text": "Commented-code block (5 lines) in client/src/components/MessageRenderer.jsx:19"}, "properties": {"repobilityId": "e424f1bf898ecf22", "scanner": "scanner-primary", "fingerprint": "17733f2e2c049be5", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-46aca039f78e822c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 client/src/lib/api.js:38"}, "properties": {"repobilityId": "088bf7ce8bc1fb90", "scanner": "scanner-primary", "fingerprint": "46aca039f78e822c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e8a7843dd74d6309", "level": "none", "message": {"text": "Commented-code block (13 lines) in client/src/lib/pptxBuilder.js:7"}, "properties": {"repobilityId": "29eaf1f71604fad6", "scanner": "scanner-primary", "fingerprint": "e8a7843dd74d6309", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-084f6b133656cbe3", "level": "none", "message": {"text": "Commented-code block (5 lines) in client/src/lib/brands.js:1"}, "properties": {"repobilityId": "9cba0f623538d0d7", "scanner": "scanner-primary", "fingerprint": "084f6b133656cbe3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b0b5e7cb1208a7cd", "level": "note", "message": {"text": "13 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "2737b8666c1f7eeb", "scanner": "scanner-primary", "fingerprint": "b0b5e7cb1208a7cd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-b5c3c5ae9af7d45e", "level": "warning", "message": {"text": "Frontend route `/thanks` has no Link/navigate to it \u2014 client/src/App.jsx"}, "properties": {"repobilityId": "569cc4680b748d27", "scanner": "scanner-primary", "fingerprint": "b5c3c5ae9af7d45e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3bea4a2ca9e9c2ad", "level": "warning", "message": {"text": "Frontend route `/goodbye` has no Link/navigate to it \u2014 client/src/App.jsx"}, "properties": {"repobilityId": "6169718029a82cf8", "scanner": "scanner-primary", "fingerprint": "3bea4a2ca9e9c2ad", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5af0937f7090be2c", "level": "warning", "message": {"text": "Frontend route `/subscribe/success` has no Link/navigate to it \u2014 client/src/App.jsx"}, "properties": {"repobilityId": "f71cc9edd2b2ade1", "scanner": "scanner-primary", "fingerprint": "5af0937f7090be2c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5f804b9c3b7fa4bb", "level": "warning", "message": {"text": "Frontend route `/privacy-settings` has no Link/navigate to it \u2014 client/src/App.jsx"}, "properties": {"repobilityId": "4ce0571c72f6b0c1", "scanner": "scanner-primary", "fingerprint": "5f804b9c3b7fa4bb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-956c2bf78ad86288", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (server/server.js:1868)"}, "properties": {"repobilityId": "08f4b432d47a8295", "scanner": "scanner-primary", "fingerprint": "956c2bf78ad86288", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6a36ca0de71b7fe9", "level": "error", "message": {"text": "Dangling fetch: POST https://openrouter.ai/api/v1/chat/completions (server/routes/v1.js:89)"}, "properties": {"repobilityId": "021396f200446811", "scanner": "scanner-primary", "fingerprint": "6a36ca0de71b7fe9", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-383cdb7fe9cebb9d", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/google"}, "properties": {"repobilityId": "1b0a48ae690ee4c2", "scanner": "scanner-primary", "fingerprint": "383cdb7fe9cebb9d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a5b3437e64c8f7b4", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/register"}, "properties": {"repobilityId": "18cb7ad5b818abae", "scanner": "scanner-primary", "fingerprint": "a5b3437e64c8f7b4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fd55aa0818a7c897", "level": "note", "message": {"text": "Unused endpoint: POST /api/auth/login"}, "properties": {"repobilityId": "adbfee01a02f645f", "scanner": "scanner-primary", "fingerprint": "fd55aa0818a7c897", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ee4aa5ddab88c9dc", "level": "note", "message": {"text": "Unused endpoint: GET /api/auth/me"}, "properties": {"repobilityId": "e69a574294276590", "scanner": "scanner-primary", "fingerprint": "ee4aa5ddab88c9dc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3b94923f366fed0e", "level": "note", "message": {"text": "Unused endpoint: GET /api/projects"}, "properties": {"repobilityId": "e47064128693534f", "scanner": "scanner-primary", "fingerprint": "3b94923f366fed0e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9ecbca60df3adf4c", "level": "note", "message": {"text": "Unused endpoint: GET /api/projects/:id"}, "properties": {"repobilityId": "d4975b54418fc69b", "scanner": "scanner-primary", "fingerprint": "9ecbca60df3adf4c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-16a480533217943d", "level": "note", "message": {"text": "Unused endpoint: POST /api/projects"}, "properties": {"repobilityId": "ff308fc1e9380e53", "scanner": "scanner-primary", "fingerprint": "16a480533217943d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3f4a46c6d6faaa73", "level": "note", "message": {"text": "Unused endpoint: PUT /api/projects/:id"}, "properties": {"repobilityId": "a43e45566b934b30", "scanner": "scanner-primary", "fingerprint": "3f4a46c6d6faaa73", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1ec3273d14ad0424", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/projects/:id"}, "properties": {"repobilityId": "380045d2aa4a5b61", "scanner": "scanner-primary", "fingerprint": "1ec3273d14ad0424", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-290013142a37490b", "level": "note", "message": {"text": "Unused endpoint: PUT /api/conversations/:id/project"}, "properties": {"repobilityId": "39bdcd7ac07f3959", "scanner": "scanner-primary", "fingerprint": "290013142a37490b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c4b0361ac0f5eeb9", "level": "note", "message": {"text": "Unused endpoint: GET /api/agents"}, "properties": {"repobilityId": "69803c77cb597131", "scanner": "scanner-primary", "fingerprint": "c4b0361ac0f5eeb9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d8dc21709e9d79c6", "level": "note", "message": {"text": "Unused endpoint: GET /api/agents/:id"}, "properties": {"repobilityId": "1b9a970ed258ccb3", "scanner": "scanner-primary", "fingerprint": "d8dc21709e9d79c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ab31d7e480a710b2", "level": "note", "message": {"text": "Unused endpoint: POST /api/agents"}, "properties": {"repobilityId": "40bf4ef0505186d4", "scanner": "scanner-primary", "fingerprint": "ab31d7e480a710b2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b405f19b320d99ed", "level": "note", "message": {"text": "Unused endpoint: PUT /api/agents/:id"}, "properties": {"repobilityId": "5114cf8f990e7ce7", "scanner": "scanner-primary", "fingerprint": "b405f19b320d99ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4f288126896fe12d", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/agents/:id"}, "properties": {"repobilityId": "c497739a0d484436", "scanner": "scanner-primary", "fingerprint": "4f288126896fe12d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a74464b0f1216462", "level": "note", "message": {"text": "Unused endpoint: GET /api/memory"}, "properties": {"repobilityId": "d0fa6a6443856a9e", "scanner": "scanner-primary", "fingerprint": "a74464b0f1216462", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3a1c5c579cf2cd4d", "level": "note", "message": {"text": "Unused endpoint: PUT /api/memory"}, "properties": {"repobilityId": "3b4b2fbbcb842e29", "scanner": "scanner-primary", "fingerprint": "3a1c5c579cf2cd4d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-86c89e97ef3b57ac", "level": "note", "message": {"text": "Unused endpoint: GET /api/preferences/models"}, "properties": {"repobilityId": "854e089e6f351a28", "scanner": "scanner-primary", "fingerprint": "86c89e97ef3b57ac", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-674b816fbdd8ff26", "level": "note", "message": {"text": "Unused endpoint: PUT /api/preferences/models"}, "properties": {"repobilityId": "ba4b228afb4607dd", "scanner": "scanner-primary", "fingerprint": "674b816fbdd8ff26", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0470e8eced199dda", "level": "note", "message": {"text": "Unused endpoint: GET /api/privacy/export"}, "properties": {"repobilityId": "6e2a582bba896004", "scanner": "scanner-primary", "fingerprint": "0470e8eced199dda", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-86cb49ad502909f1", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/privacy/account"}, "properties": {"repobilityId": "6444ab4348a9db50", "scanner": "scanner-primary", "fingerprint": "86cb49ad502909f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2e3780dcba194f52", "level": "note", "message": {"text": "Unused endpoint: POST /api/chat/debate"}, "properties": {"repobilityId": "1ab79bb36be73f78", "scanner": "scanner-primary", "fingerprint": "2e3780dcba194f52", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8724497fdb00ccd3", "level": "note", "message": {"text": "Unused endpoint: POST /api/chat/merge"}, "properties": {"repobilityId": "974464bf8a2bd9b7", "scanner": "scanner-primary", "fingerprint": "8724497fdb00ccd3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-60e78a867a1a28c9", "level": "note", "message": {"text": "Unused endpoint: GET /api/usage"}, "properties": {"repobilityId": "d4c4a5c1b4f67702", "scanner": "scanner-primary", "fingerprint": "60e78a867a1a28c9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-55890047a9ea2bbe", "level": "note", "message": {"text": "Unused endpoint: GET /api/quota"}, "properties": {"repobilityId": "64d6990a0f713e72", "scanner": "scanner-primary", "fingerprint": "55890047a9ea2bbe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-32e9ac37a764cea0", "level": "note", "message": {"text": "Unused endpoint: POST /api/credits/transfer"}, "properties": {"repobilityId": "85ad08c4e21464ce", "scanner": "scanner-primary", "fingerprint": "32e9ac37a764cea0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e9c21c7292ee8388", "level": "note", "message": {"text": "Unused endpoint: GET /api/catalog"}, "properties": {"repobilityId": "77e62a9ceae9c5fe", "scanner": "scanner-primary", "fingerprint": "e9c21c7292ee8388", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c921d242ce55dba1", "level": "note", "message": {"text": "Unused endpoint: GET /api/conversations"}, "properties": {"repobilityId": "ee46d4a3f8823931", "scanner": "scanner-primary", "fingerprint": "c921d242ce55dba1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4045c741ef650832", "level": "note", "message": {"text": "Unused endpoint: GET /api/conversations/:id"}, "properties": {"repobilityId": "d03e1858bbe42cee", "scanner": "scanner-primary", "fingerprint": "4045c741ef650832", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-24a206bd919f2f73", "level": "note", "message": {"text": "Unused endpoint: PUT /api/conversations/:id"}, "properties": {"repobilityId": "188ffeeccba470e8", "scanner": "scanner-primary", "fingerprint": "24a206bd919f2f73", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-81406ff09b73ded6", "level": "note", "message": {"text": "Unused endpoint: DELETE /api/conversations/:id"}, "properties": {"repobilityId": "465b66be1ab81bb1", "scanner": "scanner-primary", "fingerprint": "81406ff09b73ded6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c8982ec1329029f", "level": "note", "message": {"text": "Unused endpoint: POST /api/code/session"}, "properties": {"repobilityId": "8b2329f5d8499c8c", "scanner": "scanner-primary", "fingerprint": "7c8982ec1329029f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e89c3b030562126b", "level": "note", "message": {"text": "Unused endpoint: POST /api/code/session/:id/edit"}, "properties": {"repobilityId": "242669854458646f", "scanner": "scanner-primary", "fingerprint": "e89c3b030562126b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d44890fa4b665db7", "level": "note", "message": {"text": "Unused endpoint: GET /api/code/session/:id.zip"}, "properties": {"repobilityId": "c943e7430d79425a", "scanner": "scanner-primary", "fingerprint": "d44890fa4b665db7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0460984524eae5cf", "level": "note", "message": {"text": "Unused endpoint: GET /api/code/session/:id/preview/*"}, "properties": {"repobilityId": "7c0bcc469da171e0", "scanner": "scanner-primary", "fingerprint": "0460984524eae5cf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-24d819daa2be5852", "level": "note", "message": {"text": "Unused endpoint: POST /api/route"}, "properties": {"repobilityId": "cb9626cf9111d4c7", "scanner": "scanner-primary", "fingerprint": "24d819daa2be5852", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-72d08b913b763566", "level": "note", "message": {"text": "Unused endpoint: POST /api/deep-search"}, "properties": {"repobilityId": "cc4bfb7454cd6b76", "scanner": "scanner-primary", "fingerprint": "72d08b913b763566", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-88f89a9326454f53", "level": "note", "message": {"text": "Unused endpoint: POST /api/age-verify"}, "properties": {"repobilityId": "997ec4f22aa47b4b", "scanner": "scanner-primary", "fingerprint": "88f89a9326454f53", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9d2517f9eafc5297", "level": "note", "message": {"text": "Unused endpoint: POST /api/chat"}, "properties": {"repobilityId": "e64de241a83fae7d", "scanner": "scanner-primary", "fingerprint": "9d2517f9eafc5297", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a8d6210d067faf8c", "level": "note", "message": {"text": "Unused endpoint: POST /api/chat/stream"}, "properties": {"repobilityId": "16f52a4f82b6fd76", "scanner": "scanner-primary", "fingerprint": "a8d6210d067faf8c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-21ffafbe996c5c91", "level": "note", "message": {"text": "Unused endpoint: POST /api/subscribe/activate"}, "properties": {"repobilityId": "9f88dad69488cf96", "scanner": "scanner-primary", "fingerprint": "21ffafbe996c5c91", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d5d1aebd0d8c8397", "level": "note", "message": {"text": "Unused endpoint: GET /api/subscribe/confirm"}, "properties": {"repobilityId": "370582c70ae33641", "scanner": "scanner-primary", "fingerprint": "d5d1aebd0d8c8397", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9721a8bd8c654afb", "level": "note", "message": {"text": "Unused endpoint: POST /api/subscribe/:plan"}, "properties": {"repobilityId": "2917530317f0b913", "scanner": "scanner-primary", "fingerprint": "9721a8bd8c654afb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1192affce0fb004d", "level": "note", "message": {"text": "Unused endpoint: GET /api/paypal/config"}, "properties": {"repobilityId": "4f3f64c97b511b53", "scanner": "scanner-primary", "fingerprint": "1192affce0fb004d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2d5c1d8d8ab2d64a", "level": "note", "message": {"text": "Unused endpoint: GET /api/credits/packs"}, "properties": {"repobilityId": "9f1544ecd1547d1a", "scanner": "scanner-primary", "fingerprint": "2d5c1d8d8ab2d64a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-70a3c1b41971d632", "level": "note", "message": {"text": "Unused endpoint: POST /api/credits/order"}, "properties": {"repobilityId": "e89ea257ba7eca94", "scanner": "scanner-primary", "fingerprint": "70a3c1b41971d632", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-79d2a3b096c241e9", "level": "note", "message": {"text": "Unused endpoint: POST /api/credits/capture"}, "properties": {"repobilityId": "6e1335ae263c34dd", "scanner": "scanner-primary", "fingerprint": "79d2a3b096c241e9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-17805c102de7651c", "level": "note", "message": {"text": "Unused endpoint: POST /api/paypal/webhook"}, "properties": {"repobilityId": "04aa61319b09102f", "scanner": "scanner-primary", "fingerprint": "17805c102de7651c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b392093947d3e664", "level": "note", "message": {"text": "Unused endpoint: POST /api/image"}, "properties": {"repobilityId": "bee25c6eccba545c", "scanner": "scanner-primary", "fingerprint": "b392093947d3e664", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-536fc60d1287e634", "level": "note", "message": {"text": "Unused endpoint: POST /api/upload"}, "properties": {"repobilityId": "3496b47935e19b4f", "scanner": "scanner-primary", "fingerprint": "536fc60d1287e634", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}