{"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-329f01372c463cf3", "name": "Stray `console.log` in TS/JS \u2014 setup_loadfile_nodes.js:30", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 setup_loadfile_nodes.js:30"}, "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-af324c48f8e34b3d", "name": "Stray `console.log` in TS/JS \u2014 build-new-funnels.js:66", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 build-new-funnels.js:66"}, "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-251b3925d9e15d9c", "name": "Stray `console.log` in TS/JS \u2014 fix-edges-all.js:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 fix-edges-all.js:46"}, "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-bec00b3e9413d582", "name": "Stray `console.log` in TS/JS \u2014 platform/seed_global_keys.js:102", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_global_keys.js:102"}, "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-5c31473dda0ac258", "name": "Stray `console.log` in TS/JS \u2014 platform/seed_lesson_1_1.js:138", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_lesson_1_1.js:138"}, "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-db265c08afe7b71f", "name": "Custom React Flow node registered without explicit width/height \u2014 platform/seed_lesson_1_1.js:38", "shortDescription": {"text": "Custom React Flow node registered without explicit width/height \u2014 platform/seed_lesson_1_1.js:38"}, "fullDescription": {"text": "When you register a custom node type via `nodeTypes`, the RFNode object you build must include `width` and `height` props. Without them, MiniMap renders ZERO mini-nodes for that type and `fitView` underestimates the bounds (cuts off lane labels, etc.). Add `width: \u2026, height: \u2026` to the node object. See P-I.\n\nWhy: P-I in CHECKLIST.md \u2014 RF MiniMap + fitView need explicit dims on custom nodes.\nRule id: fq.rfnode.no-dims"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-625a0f29aee47c86", "name": "Stray `console.log` in TS/JS \u2014 platform/seed_finance_course.js:51", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_finance_course.js:51"}, "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-a956c57eb4e8756c", "name": "Stray `console.log` in TS/JS \u2014 platform/seed_content_funnels.js:730", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_content_funnels.js:730"}, "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-16b43309b6b78e96", "name": "Custom React Flow node registered without explicit width/height \u2014 platform/seed_content_funnels.js:45", "shortDescription": {"text": "Custom React Flow node registered without explicit width/height \u2014 platform/seed_content_funnels.js:45"}, "fullDescription": {"text": "When you register a custom node type via `nodeTypes`, the RFNode object you build must include `width` and `height` props. Without them, MiniMap renders ZERO mini-nodes for that type and `fitView` underestimates the bounds (cuts off lane labels, etc.). Add `width: \u2026, height: \u2026` to the node object. See P-I.\n\nWhy: P-I in CHECKLIST.md \u2014 RF MiniMap + fitView need explicit dims on custom nodes.\nRule id: fq.rfnode.no-dims"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b2822b19c0975ebb", "name": "Stray `console.log` in TS/JS \u2014 platform/apps/api/src/services/testSession.js:1481", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/apps/api/src/services/testSession.js:1481"}, "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-6cce8c676e4415c1", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/UserPhoto.jsx:64", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/UserPhoto.jsx:64"}, "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-da2eda64fb815c01", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/layout/Sidebar.jsx:71", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/layout/Sidebar.jsx:71"}, "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-7bdb069b9b6d506f", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/funnel/NodeLibrary.jsx:37", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/funnel/NodeLibrary.jsx:37"}, "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-2ae3e716106de95e", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/FunnelEditModal.jsx:46", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/FunnelEditModal.jsx:46"}, "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-974e6e6d046c4298", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/EnvironmentPanel.jsx:492", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/EnvironmentPanel.jsx:492"}, "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-4c385750e00ad0aa", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/FunnelTestModal.jsx:98", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/FunnelTestModal.jsx:98"}, "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-b92d7fd69d515962", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/KeysPanel.jsx:250", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/KeysPanel.jsx:250"}, "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-0255b92469652918", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/funnel/NodeTypes.jsx:64", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/funnel/NodeTypes.jsx:64"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0ffcc36f0caa7576", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Projects.jsx:12", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Projects.jsx:12"}, "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-ca50bcbd49e3788f", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Projects.jsx:43", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Projects.jsx:43"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e18668b8873c8950", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Sessions.jsx:297", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Sessions.jsx:297"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b744f13e35c8e2d8", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:121", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:121"}, "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-99c49c863579f15e", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:120", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:120"}, "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-c527fdf76c4419d7", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:106", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:106"}, "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-74bb20d25c4df00d", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Logs.jsx:105", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Logs.jsx:105"}, "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-209c4f861fd1cf73", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/FunnelEditor.jsx:414", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/FunnelEditor.jsx:414"}, "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-8f761db5faaa5370", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Bots.jsx:44", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Bots.jsx:44"}, "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-ddab8f06d8950074", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Bots.jsx:557", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Bots.jsx:557"}, "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-357470ec94c1d0c3", "name": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Users.jsx:85", "shortDescription": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Users.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-fec3b7dd7e7e9494", "name": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Broadcasts.jsx:104", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Broadcasts.jsx:104"}, "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-4fa4d58973b31f38", "name": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_connector_defs.js:182", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_connector_defs.js:182"}, "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-58a33d6417df4653", "name": "Stray `console.log` in TS/JS \u2014 platform/scripts/resync_all_channels.js:20", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/resync_all_channels.js:20"}, "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-5fc6985a7ec185d6", "name": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_funnels.js:110", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_funnels.js:110"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-00bb3bb998ca1028", "name": "Stray `console.log` in TS/JS \u2014 platform/scripts/run_full_regression.js:273", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/run_full_regression.js:273"}, "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-77aa22d266967b07", "name": "Stray `console.log` in TS/JS \u2014 platform/scripts/apply_flow_updates.js:113", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/apply_flow_updates.js:113"}, "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-48ccbaf96d93eb03", "name": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_apps_script_funnel_keys.js:86", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_apps_script_funnel_keys.js:86"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2615ae37a08d11c7", "name": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/architectureDiagram-3BPJPVTR-BkZMF8gE.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/architectureDiagram-3BPJPVTR-BkZMF8gE.js:1"}, "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-2719202e4e8f4ac7", "name": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/vennDiagram-CIIHVFJN-Dpms7Wwq.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/vennDiagram-CIIHVFJN-Dpms7Wwq.js:1"}, "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-36df39bc76be34b0", "name": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/katex-C5jXJg4s.js:256", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/katex-C5jXJg4s.js:256"}, "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-bc335972f47eeb9a", "name": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/wardley-L42UT6IY-CB-pqIph.js:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/wardley-L42UT6IY-CB-pqIph.js:35"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ecff7adaaf42df60", "name": "TODO/FIXME marker in shipping code \u2014 platform/public/admin/assets/cytoscape.esm-BHYC38rz.js:98", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 platform/public/admin/assets/cytoscape.esm-BHYC38rz.js:98"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-80e7908659b71d45", "name": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/cytoscape.esm-BHYC38rz.js:4", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/cytoscape.esm-BHYC38rz.js:4"}, "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-61e76c86998e1ad3", "name": "Insecure pattern 'direct_innerhtml_assignment' in patch_broll.py:111", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in patch_broll.py:111"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8df8369eb73b6fb8", "name": "Insecure pattern 'dangerous_innerhtml' in platform/apps/admin/src/pages/SessionDetail.jsx:106", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in platform/apps/admin/src/pages/SessionDetail.jsx:106"}, "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-7182caed700578b8", "name": "Insecure pattern 'cors_wildcard' in platform/apps/notebooklm-service/app.py:32", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in platform/apps/notebooklm-service/app.py:32"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-54f7efdad0041597", "name": "Very large file: platform/apps/api/src/services/testSession.js (2566 lines)", "shortDescription": {"text": "Very large file: platform/apps/api/src/services/testSession.js (2566 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-0745d57c8f3b3f33", "name": "Very large file: platform/apps/api/src/services/platformBotHandler.js (1137 lines)", "shortDescription": {"text": "Very large file: platform/apps/api/src/services/platformBotHandler.js (1137 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-c2385526d6fa5ba5", "name": "Very large file: platform/apps/admin/src/components/funnel/NodeEditor.jsx (1254 lines)", "shortDescription": {"text": "Very large file: platform/apps/admin/src/components/funnel/NodeEditor.jsx (1254 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": "2 test file(s) for 193 source file(s) (ratio 0.01). 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-64782e83a6956733", "name": "Node manifest has dependencies but no lockfile: platform/apps/api/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/apps/api/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-78ceaf18105e9f7c", "name": "Node manifest has dependencies but no lockfile: platform/apps/mcp/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/apps/mcp/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cdf2f9aec52fe9de", "name": "Node manifest has dependencies but no lockfile: platform/apps/worker/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/apps/worker/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5e18ab7e321219f2", "name": "Node manifest has dependencies but no lockfile: platform/apps/admin/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/apps/admin/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d34a870078a45165", "name": "Node manifest has dependencies but no lockfile: platform/packages/telegram/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/packages/telegram/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ced2cb723ad14fd9", "name": "Node manifest has dependencies but no lockfile: platform/packages/logger/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/packages/logger/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-afce13803410da02", "name": "Node manifest has dependencies but no lockfile: platform/packages/db/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/packages/db/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f7688065d956ec24", "name": "Node manifest has dependencies but no lockfile: platform/packages/claude/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/packages/claude/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-80e1a576842b4542", "name": "Node manifest has dependencies but no lockfile: platform/packages/storage/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: platform/packages/storage/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 97 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 302 placeholder/mock markers across 36 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9d79c4077342a7d0", "name": "Runtime service client appears to use placeholder configuration", "shortDescription": {"text": "Runtime service client appears to use placeholder configuration"}, "fullDescription": {"text": "A runtime source file appears to wire Supabase/Firebase/AI/payment-style clients to placeholder URLs, keys, or fallback values. In the Fable corpus this often means the UI/API shape is present while the backend service is not actually configured."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "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, lockfile. 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-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ed0ab2b088bd7b72", "name": "Agent instruction/config may expose a secret: platform/CLAUDE.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: platform/CLAUDE.md"}, "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-4525b0020032bf29", "name": "Agent authority lacks a verifier contract: platform/CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: platform/CLAUDE.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b278c8c8a21249b8", "name": "Legacy-named symbol `business_process_v2` in setup_loadfile_nodes.js:17", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in setup_loadfile_nodes.js:17"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-846cce7046dd651c", "name": "Commented-code block (7 lines) in fix-edges-all.js:18", "shortDescription": {"text": "Commented-code block (7 lines) in fix-edges-all.js:18"}, "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-5f0297383a5ea9f7", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/constants.js:8", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/constants.js:8"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dac81005fa2b7354", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/config/prerequisites.js:18", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/config/prerequisites.js:18"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-bf6b6380e29ce180", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-5-3-balance-process/bot.config.js", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-5-3-balance-process/bot.config.js:8"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-669919988e2924fd", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-5-3-balance-process/index.js:22", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-5-3-balance-process/index.js:22"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f8c8e438ccc7e98d", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-5-team-instructions/bot.config.", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-5-team-instructions/bot.config.js:8"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-210059e5c2135fce", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-5-team-instructions/index.js:19", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-5-team-instructions/index.js:19"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-68c65c42a52c0f6c", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-1-process-update/bot.config.js:", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-1-process-update/bot.config.js:9"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c768e328fb24b3f4", "name": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-1-process-update/index.js:128", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-1-process-update/index.js:128"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-55ce80b7e0c35520", "name": "Commented-code block (8 lines) in platform/apps/api/src/routes/webhook.js:166", "shortDescription": {"text": "Commented-code block (8 lines) in platform/apps/api/src/routes/webhook.js:166"}, "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-4a6da9777eabe396", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/routes/webhook.js:197", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/routes/webhook.js:197"}, "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-348321f49659bdfa", "name": "Legacy-named symbol `business_process_v2` in platform/apps/api/src/routes/sessions.js:489", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/api/src/routes/sessions.js:489"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a8079efb4a149f8f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/routes/sessions.js:362", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/routes/sessions.js:362"}, "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-8fd203c80b38c391", "name": "Legacy-named symbol `business_process_v2` in platform/apps/api/src/services/testSession.js:35", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/api/src/services/testSession.js:35"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6cb3b66dcd7d4d28", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/testSession.js:982", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/testSession.js:982"}, "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-8b3373bcf54eb498", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/channelSync.js:112", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/channelSync.js:112"}, "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-c175d0329dc6e513", "name": "Commented-code block (5 lines) in platform/apps/api/src/services/platformBotHandler.js:445", "shortDescription": {"text": "Commented-code block (5 lines) in platform/apps/api/src/services/platformBotHandler.js:445"}, "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-2880838df8e30af9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/platformBotHandler.js:257", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/platformBotHandler.js:257"}, "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-dc8ac58afd76cb9e", "name": "Legacy-named symbol `business_process_v2` in platform/apps/mcp/src/tools-debug.js:189", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/mcp/src/tools-debug.js:189"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8b6be8224bf1b0b1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/worker/src/index.js:368", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/worker/src/index.js:368"}, "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-0712ff81817b472a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/admin/src/api/client.js:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/admin/src/api/client.js:18"}, "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-082ede8017f5e946", "name": "Legacy-named symbol `business_process_v2` in platform/apps/admin/src/components/funnel/NodeEditor.jsx:849", "shortDescription": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/admin/src/components/funnel/NodeEditor.jsx:849"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f04f2c6524ac08db", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/scripts/run_full_regression.js:17", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/scripts/run_full_regression.js:17"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9ecbc993bdea7c71", "name": "Legacy-named symbol `loadfile_business_process_v2` in platform/scripts/apply_flow_updates.js:17", "shortDescription": {"text": "Legacy-named symbol `loadfile_business_process_v2` in platform/scripts/apply_flow_updates.js:17"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8061ca5cd3c67d44", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/packages/claude/src/wrapper.js:232", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/packages/claude/src/wrapper.js:232"}, "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-239ac40dfceb846d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 platform/public/admin/assets/katex-C5jXJg4s.js:252", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/public/admin/assets/katex-C5jXJg4s.js:252"}, "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-100b6131f2533e8c", "name": "Legacy-named symbol `AsOld` in platform/public/admin/assets/wardley-L42UT6IY-CB-pqIph.js:5", "shortDescription": {"text": "Legacy-named symbol `AsOld` in platform/public/admin/assets/wardley-L42UT6IY-CB-pqIph.js:5"}, "fullDescription": {"text": "Names with suffixes like `_old`, `_v1`, `_deprecated` usually indicate replaced-but-not-removed code (typical AI-coder leftover). Confirm and delete, or rename if it's the active version."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b0b7578dd2a289b6", "name": "26 env vars used in code but missing from .env.example", "shortDescription": {"text": "26 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_LOGIN`, `ADMIN_TELEGRAM_ID`, `APPS_SCRIPT_TIMEOUT_MS`, `APPS_SCRIPT_URL`, `APP_BASE_URL`, `BOT_FILES_DIR`, `DATA_DIR`, `FALLBACK_TIMEOUT_MS` + 18 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-2c04133e54348533", "name": "Near-duplicate function bodies in 2 places", "shortDescription": {"text": "Near-duplicate function bodies in 2 places"}, "fullDescription": {"text": "Functions with the same first-5-line body hash:\nplatform/apps/notebooklm-service/app.py:add_source, platform/apps/notebooklm-service/app.py:query_notebook\n\nThis is *the* AI-coder failure mode (4\u00d7 more duplication in vibe-coded repos \u2014 see https://jw.hn/ai-code-hygiene). Consolidate or document why they're separate."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8da4c54b95599f2d", "name": "Frontend route `/funnel/:botId` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `/funnel/:botId` has no Link/navigate to it \u2014 platform/apps/admin/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-10af588423c792be", "name": "Frontend route `/funnel/:botId/analytics` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `/funnel/:botId/analytics` has no Link/navigate to it \u2014 platform/apps/admin/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-cd2c3a6086676159", "name": "Frontend route `funnels` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `funnels` has no Link/navigate to it \u2014 platform/apps/admin/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-c9ca7442d19c4d2a", "name": "Frontend route `projects` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `projects` has no Link/navigate to it \u2014 platform/apps/admin/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-f156f1c736641ff3", "name": "Frontend route `dashboard` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `dashboard` has no Link/navigate to it \u2014 platform/apps/admin/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-3ee247854b670a2f", "name": "Frontend route `content` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `content` has no Link/navigate to it \u2014 platform/apps/admin/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-f7ef41dc4eeab520", "name": "Frontend route `broadcasts` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `broadcasts` has no Link/navigate to it \u2014 platform/apps/admin/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-30245c7168c2a2ab", "name": "Frontend route `connectors` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `connectors` has no Link/navigate to it \u2014 platform/apps/admin/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-3f97e65bc59abd33", "name": "Frontend route `bots` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `bots` has no Link/navigate to it \u2014 platform/apps/admin/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-455d704d01da2c24", "name": "Frontend route `bots/:botId/sessions` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `bots/:botId/sessions` has no Link/navigate to it \u2014 platform/apps/admin/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-9e4971a43c48f47b", "name": "Frontend route `sessions` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `sessions` has no Link/navigate to it \u2014 platform/apps/admin/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-c832e7b69ecf85bb", "name": "Frontend route `sessions/:id` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `sessions/:id` has no Link/navigate to it \u2014 platform/apps/admin/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-64262fb7d8f3d85e", "name": "Frontend route `users` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `users` has no Link/navigate to it \u2014 platform/apps/admin/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-8284781fbb7f6123", "name": "Frontend route `subscribers` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `subscribers` has no Link/navigate to it \u2014 platform/apps/admin/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-47a9c4b3491eb404", "name": "Frontend route `users/:id` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `users/:id` has no Link/navigate to it \u2014 platform/apps/admin/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-725bc93719b54b56", "name": "Frontend route `subscribers/:id` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `subscribers/:id` has no Link/navigate to it \u2014 platform/apps/admin/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-9afb9f293393889e", "name": "Frontend route `api-logs` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `api-logs` has no Link/navigate to it \u2014 platform/apps/admin/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-a73ca485a68a0d74", "name": "Frontend route `errors` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `errors` has no Link/navigate to it \u2014 platform/apps/admin/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-161249ba0c4ba03c", "name": "Frontend route `logs` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `logs` has no Link/navigate to it \u2014 platform/apps/admin/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-e9bde4790a075778", "name": "Frontend route `settings` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 platform/apps/admin/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-8e4a72114ccb2b63", "name": "Frontend route `mcp` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx", "shortDescription": {"text": "Frontend route `mcp` has no Link/navigate to it \u2014 platform/apps/admin/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-625e6bffe3ce8ff1", "name": "FastAPI POST `create_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:81", "shortDescription": {"text": "FastAPI POST `create_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:81"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-11b8a7be702c0f06", "name": "FastAPI POST `add_source` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:97", "shortDescription": {"text": "FastAPI POST `add_source` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:97"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-52cedebd475bf782", "name": "FastAPI POST `query_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:134", "shortDescription": {"text": "FastAPI POST `query_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:134"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-ea589753bbc2d98d", "name": "FastAPI DELETE `delete_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:168", "shortDescription": {"text": "FastAPI DELETE `delete_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:168"}, "fullDescription": {"text": "`@router.delete` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-fbd6be88f702982f", "name": "Dangling fetch: GET https://api.telegram.org/file/bot${token}/${filePath} (platform/apps/api/src/routes/sessions.js:373)", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/file/bot${token}/${filePath} (platform/apps/api/src/routes/sessions.js:373)"}, "fullDescription": {"text": "`platform/apps/api/src/routes/sessions.js:373` calls `GET https://api.telegram.org/file/bot${token}/${filePath}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/file/bot/<p>/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-33bc755d6ac1bb5b", "name": "Dangling fetch: POST https://api.telegram.org/bot${token}/editMessageText (platform/apps/api/src/routes/sessions.js:558)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/editMessageText (platform/apps/api/src/routes/sessions.js:558)"}, "fullDescription": {"text": "`platform/apps/api/src/routes/sessions.js:558` calls `POST https://api.telegram.org/bot${token}/editMessageText` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/editmessagetext`\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-81d7642cc520991a", "name": "Dangling fetch: POST https://api.telegram.org/bot${token}/deleteMessage (platform/apps/api/src/routes/sessions.js:599)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/deleteMessage (platform/apps/api/src/routes/sessions.js:599)"}, "fullDescription": {"text": "`platform/apps/api/src/routes/sessions.js:599` calls `POST https://api.telegram.org/bot${token}/deleteMessage` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/deletemessage`\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-8022b9eccb9a7e0b", "name": "Dangling fetch: POST https://api.telegram.org/bot${notifyToken}/sendMessage (platform/apps/api/src/services/testSession.", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${notifyToken}/sendMessage (platform/apps/api/src/services/testSession.js:1836)"}, "fullDescription": {"text": "`platform/apps/api/src/services/testSession.js:1836` calls `POST https://api.telegram.org/bot${notifyToken}/sendMessage` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/sendmessage`\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-bc3d95586723b744", "name": "Dangling fetch: GET https://api.telegram.org/bot${token}/getMe (platform/apps/api/src/services/channelSync.js:61)", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getMe (platform/apps/api/src/services/channelSync.js:61)"}, "fullDescription": {"text": "`platform/apps/api/src/services/channelSync.js:61` calls `GET https://api.telegram.org/bot${token}/getMe` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getme`\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-43154d03cfbdc38f", "name": "Dangling fetch: POST https://api.telegram.org/bot${token}/setWebhook (platform/apps/api/src/services/channelSync.js:112)", "shortDescription": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/setWebhook (platform/apps/api/src/services/channelSync.js:112)"}, "fullDescription": {"text": "`platform/apps/api/src/services/channelSync.js:112` calls `POST https://api.telegram.org/bot${token}/setWebhook` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/setwebhook`\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-79638788a3bd1aef", "name": "Dangling fetch: GET https://api.telegram.org/bot${token}/getWebhookInfo (platform/apps/api/src/services/channelSync.js:1", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getWebhookInfo (platform/apps/api/src/services/channelSync.js:123)"}, "fullDescription": {"text": "`platform/apps/api/src/services/channelSync.js:123` calls `GET https://api.telegram.org/bot${token}/getWebhookInfo` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getwebhookinfo`\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-408cfe2546b07dc0", "name": "Dangling fetch: POST https://graph.facebook.com/v23.0/${appId}/subscriptions (platform/apps/api/src/services/channelSync", "shortDescription": {"text": "Dangling fetch: POST https://graph.facebook.com/v23.0/${appId}/subscriptions (platform/apps/api/src/services/channelSync.js:159)"}, "fullDescription": {"text": "`platform/apps/api/src/services/channelSync.js:159` calls `POST https://graph.facebook.com/v23.0/${appId}/subscriptions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/graph.facebook.com/v23.0/<p>/subscriptions`\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-e18ac300b470a2bb", "name": "Dangling fetch: GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId} (platform/apps/api/src/services/platf", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId} (platform/apps/api/src/services/platformBotHandler.js:159)"}, "fullDescription": {"text": "`platform/apps/api/src/services/platformBotHandler.js:159` calls `GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getfile`\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-7b320767c4f1e28a", "name": "Dangling fetch: POST https://api.openai.com/v1/audio/transcriptions (platform/apps/api/src/services/platformBotHandler.j", "shortDescription": {"text": "Dangling fetch: POST https://api.openai.com/v1/audio/transcriptions (platform/apps/api/src/services/platformBotHandler.js:223)"}, "fullDescription": {"text": "`platform/apps/api/src/services/platformBotHandler.js:223` calls `POST https://api.openai.com/v1/audio/transcriptions` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.openai.com/v1/audio/transcriptions`\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-3e73ee9cd1385bae", "name": "Dangling fetch: GET https://api.telegram.org/bot${token}/getUserProfilePhotos?user_id=${telegramId}&limit=1 (platform/ap", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getUserProfilePhotos?user_id=${telegramId}&limit=1 (platform/apps/api/src/services/platformBotHandler.js:246)"}, "fullDescription": {"text": "`platform/apps/api/src/services/platformBotHandler.js:246` calls `GET https://api.telegram.org/bot${token}/getUserProfilePhotos?user_id=${telegramId}&limit=1` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getuserprofilephotos`\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-4eed8703e74280ec", "name": "Dangling fetch: GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId} (platform/apps/api/src/services/platf", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId} (platform/apps/api/src/services/platformBotHandler.js:257)"}, "fullDescription": {"text": "`platform/apps/api/src/services/platformBotHandler.js:257` calls `GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getfile`\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-5fd5941af6d3e801", "name": "Dangling fetch: GET /api/users/${userId}/photo (platform/apps/admin/src/components/UserPhoto.jsx:20)", "shortDescription": {"text": "Dangling fetch: GET /api/users/${userId}/photo (platform/apps/admin/src/components/UserPhoto.jsx:20)"}, "fullDescription": {"text": "`platform/apps/admin/src/components/UserPhoto.jsx:20` calls `GET /api/users/${userId}/photo` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/users/<p>/photo`\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-20f9e0beb36e98df", "name": "Dangling fetch: GET /api/users/${userId}/photo (platform/apps/admin/src/components/UserPhoto.jsx:77)", "shortDescription": {"text": "Dangling fetch: GET /api/users/${userId}/photo (platform/apps/admin/src/components/UserPhoto.jsx:77)"}, "fullDescription": {"text": "`platform/apps/admin/src/components/UserPhoto.jsx:77` calls `GET /api/users/${userId}/photo` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/users/<p>/photo`\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-9846457ba1a3a2e4", "name": "Dangling fetch: GET https://api.telegram.org/bot${String(token).trim()}/getMe (platform/apps/admin/src/components/funnel", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${String(token).trim()}/getMe (platform/apps/admin/src/components/funnel/EnvironmentPanel.jsx:259)"}, "fullDescription": {"text": "`platform/apps/admin/src/components/funnel/EnvironmentPanel.jsx:259` calls `GET https://api.telegram.org/bot${String(token).trim()}/getMe` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getme`\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-c798ec39f4c39554", "name": "Dangling fetch: GET https://api.telegram.org/bot${token.trim()}/getMe (platform/apps/admin/src/pages/Connectors.jsx:7)", "shortDescription": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token.trim()}/getMe (platform/apps/admin/src/pages/Connectors.jsx:7)"}, "fullDescription": {"text": "`platform/apps/admin/src/pages/Connectors.jsx:7` calls `GET https://api.telegram.org/bot${token.trim()}/getMe` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/https:/api.telegram.org/bot/<p>/getme`\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-7f01f61e6096ac8b", "name": "Dangling fetch: POST https://api.openai.com/v1/chat/completions (platform/packages/claude/src/wrapper.js:232)", "shortDescription": {"text": "Dangling fetch: POST https://api.openai.com/v1/chat/completions (platform/packages/claude/src/wrapper.js:232)"}, "fullDescription": {"text": "`platform/packages/claude/src/wrapper.js:232` calls `POST https://api.openai.com/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:/api.openai.com/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-00f7772acd4236ed", "name": "Unused endpoint: GET /notebooks", "shortDescription": {"text": "Unused endpoint: GET /notebooks"}, "fullDescription": {"text": "`platform/apps/notebooklm-service/app.py` declares `GET /notebooks` 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-f22375709e28e8b0", "name": "Unused endpoint: POST /notebooks", "shortDescription": {"text": "Unused endpoint: POST /notebooks"}, "fullDescription": {"text": "`platform/apps/notebooklm-service/app.py` declares `POST /notebooks` 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-3be10e2bd7df86b3", "name": "Unused endpoint: POST /notebooks/{notebook_id}/sources", "shortDescription": {"text": "Unused endpoint: POST /notebooks/{notebook_id}/sources"}, "fullDescription": {"text": "`platform/apps/notebooklm-service/app.py` declares `POST /notebooks/{notebook_id}/sources` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7d6331595dbb2791", "name": "Unused endpoint: POST /notebooks/{notebook_id}/query", "shortDescription": {"text": "Unused endpoint: POST /notebooks/{notebook_id}/query"}, "fullDescription": {"text": "`platform/apps/notebooklm-service/app.py` declares `POST /notebooks/{notebook_id}/query` 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-dfd336506aa5e6df", "name": "Unused endpoint: DELETE /notebooks/{notebook_id}", "shortDescription": {"text": "Unused endpoint: DELETE /notebooks/{notebook_id}"}, "fullDescription": {"text": "`platform/apps/notebooklm-service/app.py` declares `DELETE /notebooks/{notebook_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-dee3a0ace2bb985c", "name": "Unused endpoint: USE /bot-files", "shortDescription": {"text": "Unused endpoint: USE /bot-files"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /bot-files` 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-e7249f2f256161b5", "name": "Unused endpoint: USE /webhook", "shortDescription": {"text": "Unused endpoint: USE /webhook"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /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-728e92394c568abf", "name": "Unused endpoint: USE /api/projects", "shortDescription": {"text": "Unused endpoint: USE /api/projects"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /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-ab7438d173aea4ec", "name": "Unused endpoint: USE /api/bots", "shortDescription": {"text": "Unused endpoint: USE /api/bots"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/bots` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8636dd48e48d1da9", "name": "Unused endpoint: USE /api/sessions", "shortDescription": {"text": "Unused endpoint: USE /api/sessions"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/sessions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4ff40cb10f7c8519", "name": "Unused endpoint: USE /api/users", "shortDescription": {"text": "Unused endpoint: USE /api/users"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/users` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-013e0d7c58374e34", "name": "Unused endpoint: USE /api/funnels", "shortDescription": {"text": "Unused endpoint: USE /api/funnels"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/funnels` 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-2a48048f3c793de1", "name": "Unused endpoint: USE /api/connectors", "shortDescription": {"text": "Unused endpoint: USE /api/connectors"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/connectors` 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-32ee27e9f9ae5691", "name": "Unused endpoint: USE /api/saved-connectors", "shortDescription": {"text": "Unused endpoint: USE /api/saved-connectors"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/saved-connectors` 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-38a323166190b71a", "name": "Unused endpoint: USE /api/system-keys", "shortDescription": {"text": "Unused endpoint: USE /api/system-keys"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/system-keys` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d93a530ce10d47d9", "name": "Unused endpoint: USE /api/admin", "shortDescription": {"text": "Unused endpoint: USE /api/admin"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/admin` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-da48c098aa00614d", "name": "Unused endpoint: USE /api/broadcasts", "shortDescription": {"text": "Unused endpoint: USE /api/broadcasts"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/broadcasts` 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-4df67aa27a99eee8", "name": "Unused endpoint: USE /api/mcp", "shortDescription": {"text": "Unused endpoint: USE /api/mcp"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/mcp` 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-501f87ebb8050563", "name": "Unused endpoint: USE /api/mcp-edit", "shortDescription": {"text": "Unused endpoint: USE /api/mcp-edit"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/mcp-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-903c59692f77f6ff", "name": "Unused endpoint: USE /api/mcp-debug", "shortDescription": {"text": "Unused endpoint: USE /api/mcp-debug"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /api/mcp-debug` 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-95e266019920938e", "name": "Unused endpoint: USE /mcp", "shortDescription": {"text": "Unused endpoint: USE /mcp"}, "fullDescription": {"text": "`platform/apps/api/src/index.js` declares `USE /mcp` 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-ca5756175765b49d", "name": "Unused endpoint: GET /:id", "shortDescription": {"text": "Unused endpoint: GET /:id"}, "fullDescription": {"text": "`platform/apps/api/src/middleware/validateParams.js` declares `GET /: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-18bd2efa3e17ad5c", "name": "Unused endpoint: GET /:botId", "shortDescription": {"text": "Unused endpoint: GET /:botId"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `GET /:botId` 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-adfb2700a5fba328", "name": "Unused endpoint: PUT /:botId", "shortDescription": {"text": "Unused endpoint: PUT /:botId"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `PUT /:botId` 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-18f74cd9e71e19ab", "name": "Unused endpoint: GET /:botId/export", "shortDescription": {"text": "Unused endpoint: GET /:botId/export"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `GET /:botId/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-c82be50d3bc695b8", "name": "Unused endpoint: POST /:botId/import", "shortDescription": {"text": "Unused endpoint: POST /:botId/import"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `POST /:botId/import` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5e8f3bdc9229c562", "name": "Unused endpoint: GET /:botId/keys", "shortDescription": {"text": "Unused endpoint: GET /:botId/keys"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `GET /:botId/keys` 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-a919ad0b285e0e7b", "name": "Unused endpoint: PUT /:botId/keys", "shortDescription": {"text": "Unused endpoint: PUT /:botId/keys"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `PUT /:botId/keys` 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-672399cc8bfb85d4", "name": "Unused endpoint: DELETE /:botId/keys/:key", "shortDescription": {"text": "Unused endpoint: DELETE /:botId/keys/:key"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `DELETE /:botId/keys/:key` 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-98454545203f7f37", "name": "Unused endpoint: POST /:botId/homework-done", "shortDescription": {"text": "Unused endpoint: POST /:botId/homework-done"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `POST /:botId/homework-done` 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-d388fb2d9975eef2", "name": "Unused endpoint: POST /:botId/sync-channels", "shortDescription": {"text": "Unused endpoint: POST /:botId/sync-channels"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `POST /:botId/sync-channels` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-105e263aa7f10c1a", "name": "Unused endpoint: GET /:botId/keys/:key/reveal", "shortDescription": {"text": "Unused endpoint: GET /:botId/keys/:key/reveal"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `GET /:botId/keys/:key/reveal` 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-8dc44bdc90f89fbc", "name": "Unused endpoint: POST /:botId/edges", "shortDescription": {"text": "Unused endpoint: POST /:botId/edges"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `POST /:botId/edges` 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-ec0380c2532605fc", "name": "Unused endpoint: PUT /:botId/edges", "shortDescription": {"text": "Unused endpoint: PUT /:botId/edges"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `PUT /:botId/edges` 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-5cceca3f6bdb2261", "name": "Unused endpoint: DELETE /:botId/edges/:edgeId", "shortDescription": {"text": "Unused endpoint: DELETE /:botId/edges/:edgeId"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `DELETE /:botId/edges/:edgeId` 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-3962ff42a429cffe", "name": "Unused endpoint: GET /:botId/nodes/:nodeId/stats", "shortDescription": {"text": "Unused endpoint: GET /:botId/nodes/:nodeId/stats"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `GET /:botId/nodes/:nodeId/stats` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2a68b47955264fff", "name": "Unused endpoint: GET /:botId/analytics", "shortDescription": {"text": "Unused endpoint: GET /:botId/analytics"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `GET /:botId/analytics` 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-3087f0b79caed3dd", "name": "Unused endpoint: POST /:botId/check-prerequisites", "shortDescription": {"text": "Unused endpoint: POST /:botId/check-prerequisites"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `POST /:botId/check-prerequisites` 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-89fd5687e7760b60", "name": "Unused endpoint: POST /:botId/upload-file", "shortDescription": {"text": "Unused endpoint: POST /:botId/upload-file"}, "fullDescription": {"text": "`platform/apps/api/src/routes/funnels.js` declares `POST /:botId/upload-file` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-618721b912bad1c2", "name": "Unused endpoint: POST /login", "shortDescription": {"text": "Unused endpoint: POST /login"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `POST /login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-99fc36db98c134ce", "name": "Unused endpoint: POST /logout", "shortDescription": {"text": "Unused endpoint: POST /logout"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `POST /logout` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4629fc2f2a182ac9", "name": "Unused endpoint: GET /analytics", "shortDescription": {"text": "Unused endpoint: GET /analytics"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `GET /analytics` 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-1515654f1d0fdbfe", "name": "Unused endpoint: GET /errors", "shortDescription": {"text": "Unused endpoint: GET /errors"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `GET /errors` 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-2d00fdf5ded225e6", "name": "Unused endpoint: PATCH /errors/:id/resolve", "shortDescription": {"text": "Unused endpoint: PATCH /errors/:id/resolve"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `PATCH /errors/:id/resolve` 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-0509c1631f349a45", "name": "Unused endpoint: GET /sessions/unread-count", "shortDescription": {"text": "Unused endpoint: GET /sessions/unread-count"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `GET /sessions/unread-count` 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-b15d518d538de57d", "name": "Unused endpoint: GET /sessions", "shortDescription": {"text": "Unused endpoint: GET /sessions"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `GET /sessions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1308d862172c711d", "name": "Unused endpoint: GET /api-logs", "shortDescription": {"text": "Unused endpoint: GET /api-logs"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `GET /api-logs` 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-2f34bb57423f5a53", "name": "Unused endpoint: POST /bots/:id/run-regression", "shortDescription": {"text": "Unused endpoint: POST /bots/:id/run-regression"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `POST /bots/:id/run-regression` 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-ecc204cf90867770", "name": "Unused endpoint: POST /bots/:id/webhook-test", "shortDescription": {"text": "Unused endpoint: POST /bots/:id/webhook-test"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `POST /bots/:id/webhook-test` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1abca45c20ef4632", "name": "Unused endpoint: POST /projects/:slug/run-regressions", "shortDescription": {"text": "Unused endpoint: POST /projects/:slug/run-regressions"}, "fullDescription": {"text": "`platform/apps/api/src/routes/admin.js` declares `POST /projects/:slug/run-regressions` 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/18886"}, "properties": {"repository": "San4ez-mc/potoky", "repoUrl": "https://github.com/San4ez-mc/potoky", "branch": "main"}, "results": [{"ruleId": "scanner-329f01372c463cf3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 setup_loadfile_nodes.js:30"}, "properties": {"repobilityId": "ac7c18283866f392", "scanner": "scanner-primary", "fingerprint": "329f01372c463cf3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-af324c48f8e34b3d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 build-new-funnels.js:66"}, "properties": {"repobilityId": "76e29b778b0febd4", "scanner": "scanner-primary", "fingerprint": "af324c48f8e34b3d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-251b3925d9e15d9c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 fix-edges-all.js:46"}, "properties": {"repobilityId": "b419cd3aad7d466d", "scanner": "scanner-primary", "fingerprint": "251b3925d9e15d9c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bec00b3e9413d582", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_global_keys.js:102"}, "properties": {"repobilityId": "8a6e489797345bdf", "scanner": "scanner-primary", "fingerprint": "bec00b3e9413d582", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5c31473dda0ac258", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_lesson_1_1.js:138"}, "properties": {"repobilityId": "8a9df9a8ef472ca6", "scanner": "scanner-primary", "fingerprint": "5c31473dda0ac258", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-db265c08afe7b71f", "level": "warning", "message": {"text": "Custom React Flow node registered without explicit width/height \u2014 platform/seed_lesson_1_1.js:38"}, "properties": {"repobilityId": "d9ddc1aef06bd5bb", "scanner": "scanner-primary", "fingerprint": "db265c08afe7b71f", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.rfnode.no-dims"]}}, {"ruleId": "scanner-625a0f29aee47c86", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_finance_course.js:51"}, "properties": {"repobilityId": "a28193b342037aec", "scanner": "scanner-primary", "fingerprint": "625a0f29aee47c86", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a956c57eb4e8756c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/seed_content_funnels.js:730"}, "properties": {"repobilityId": "cc29ff98ac01241d", "scanner": "scanner-primary", "fingerprint": "a956c57eb4e8756c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-16b43309b6b78e96", "level": "warning", "message": {"text": "Custom React Flow node registered without explicit width/height \u2014 platform/seed_content_funnels.js:45"}, "properties": {"repobilityId": "4f15076d82b161aa", "scanner": "scanner-primary", "fingerprint": "16b43309b6b78e96", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.rfnode.no-dims"]}}, {"ruleId": "scanner-b2822b19c0975ebb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/apps/api/src/services/testSession.js:1481"}, "properties": {"repobilityId": "5564329ed645810c", "scanner": "scanner-primary", "fingerprint": "b2822b19c0975ebb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6cce8c676e4415c1", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/UserPhoto.jsx:64"}, "properties": {"repobilityId": "b98c507331327230", "scanner": "scanner-primary", "fingerprint": "6cce8c676e4415c1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-da2eda64fb815c01", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/layout/Sidebar.jsx:71"}, "properties": {"repobilityId": "6a04c6df386b79a2", "scanner": "scanner-primary", "fingerprint": "da2eda64fb815c01", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7bdb069b9b6d506f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/funnel/NodeLibrary.jsx:37"}, "properties": {"repobilityId": "3a5cd19f7aae872b", "scanner": "scanner-primary", "fingerprint": "7bdb069b9b6d506f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2ae3e716106de95e", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/FunnelEditModal.jsx:46"}, "properties": {"repobilityId": "08b1fc583c39b72d", "scanner": "scanner-primary", "fingerprint": "2ae3e716106de95e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-974e6e6d046c4298", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/EnvironmentPanel.jsx:492"}, "properties": {"repobilityId": "84136c5406086bc2", "scanner": "scanner-primary", "fingerprint": "974e6e6d046c4298", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-4c385750e00ad0aa", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/FunnelTestModal.jsx:98"}, "properties": {"repobilityId": "ff4a12ee537e9c1e", "scanner": "scanner-primary", "fingerprint": "4c385750e00ad0aa", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-b92d7fd69d515962", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/components/funnel/KeysPanel.jsx:250"}, "properties": {"repobilityId": "00caaa629e424996", "scanner": "scanner-primary", "fingerprint": "b92d7fd69d515962", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-0255b92469652918", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/components/funnel/NodeTypes.jsx:64"}, "properties": {"repobilityId": "f68078189223906b", "scanner": "scanner-primary", "fingerprint": "0255b92469652918", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0ffcc36f0caa7576", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Projects.jsx:12"}, "properties": {"repobilityId": "f448d957b7bf258e", "scanner": "scanner-primary", "fingerprint": "0ffcc36f0caa7576", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-ca50bcbd49e3788f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Projects.jsx:43"}, "properties": {"repobilityId": "203a112fb0a531b9", "scanner": "scanner-primary", "fingerprint": "ca50bcbd49e3788f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e18668b8873c8950", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Sessions.jsx:297"}, "properties": {"repobilityId": "39f0ef3ef8de865c", "scanner": "scanner-primary", "fingerprint": "e18668b8873c8950", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b744f13e35c8e2d8", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:121"}, "properties": {"repobilityId": "93af4d52b5e761fb", "scanner": "scanner-primary", "fingerprint": "b744f13e35c8e2d8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-99c49c863579f15e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:120"}, "properties": {"repobilityId": "db7f8e0c4d53d175", "scanner": "scanner-primary", "fingerprint": "99c49c863579f15e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c527fdf76c4419d7", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 platform/apps/admin/src/pages/SessionDetail.jsx:106"}, "properties": {"repobilityId": "30bead8fc47ea750", "scanner": "scanner-primary", "fingerprint": "c527fdf76c4419d7", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-74bb20d25c4df00d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Logs.jsx:105"}, "properties": {"repobilityId": "a5bfbceec4a24470", "scanner": "scanner-primary", "fingerprint": "74bb20d25c4df00d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-209c4f861fd1cf73", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/FunnelEditor.jsx:414"}, "properties": {"repobilityId": "ffa2cf84a00381b6", "scanner": "scanner-primary", "fingerprint": "209c4f861fd1cf73", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8f761db5faaa5370", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Bots.jsx:44"}, "properties": {"repobilityId": "6d7f2e9557dab7c2", "scanner": "scanner-primary", "fingerprint": "8f761db5faaa5370", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-ddab8f06d8950074", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Bots.jsx:557"}, "properties": {"repobilityId": "0a6e558025b74989", "scanner": "scanner-primary", "fingerprint": "ddab8f06d8950074", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-357470ec94c1d0c3", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 platform/apps/admin/src/pages/Users.jsx:85"}, "properties": {"repobilityId": "de16ee4a44cb718a", "scanner": "scanner-primary", "fingerprint": "357470ec94c1d0c3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-fec3b7dd7e7e9494", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 platform/apps/admin/src/pages/Broadcasts.jsx:104"}, "properties": {"repobilityId": "3acdfc768afaae82", "scanner": "scanner-primary", "fingerprint": "fec3b7dd7e7e9494", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4fa4d58973b31f38", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_connector_defs.js:182"}, "properties": {"repobilityId": "e79a490eb8226bf4", "scanner": "scanner-primary", "fingerprint": "4fa4d58973b31f38", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-58a33d6417df4653", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/resync_all_channels.js:20"}, "properties": {"repobilityId": "d84fee2f120229a6", "scanner": "scanner-primary", "fingerprint": "58a33d6417df4653", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5fc6985a7ec185d6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_funnels.js:110"}, "properties": {"repobilityId": "cef6dbbdf0c788a6", "scanner": "scanner-primary", "fingerprint": "5fc6985a7ec185d6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-00bb3bb998ca1028", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/run_full_regression.js:273"}, "properties": {"repobilityId": "d20391906ec39196", "scanner": "scanner-primary", "fingerprint": "00bb3bb998ca1028", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-77aa22d266967b07", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/apply_flow_updates.js:113"}, "properties": {"repobilityId": "3ea500d5b6c48567", "scanner": "scanner-primary", "fingerprint": "77aa22d266967b07", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-48ccbaf96d93eb03", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/scripts/seed_apps_script_funnel_keys.js:86"}, "properties": {"repobilityId": "9371dc3f5d555b5b", "scanner": "scanner-primary", "fingerprint": "48ccbaf96d93eb03", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2615ae37a08d11c7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/architectureDiagram-3BPJPVTR-BkZMF8gE.js:1"}, "properties": {"repobilityId": "abb6239ddcf09823", "scanner": "scanner-primary", "fingerprint": "2615ae37a08d11c7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2719202e4e8f4ac7", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/vennDiagram-CIIHVFJN-Dpms7Wwq.js:1"}, "properties": {"repobilityId": "fb8626f03015a22e", "scanner": "scanner-primary", "fingerprint": "2719202e4e8f4ac7", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-36df39bc76be34b0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/katex-C5jXJg4s.js:256"}, "properties": {"repobilityId": "1c3688c846e1591b", "scanner": "scanner-primary", "fingerprint": "36df39bc76be34b0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-bc335972f47eeb9a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/wardley-L42UT6IY-CB-pqIph.js:35"}, "properties": {"repobilityId": "ef4a94b71ea22cb8", "scanner": "scanner-primary", "fingerprint": "bc335972f47eeb9a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ecff7adaaf42df60", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 platform/public/admin/assets/cytoscape.esm-BHYC38rz.js:98"}, "properties": {"repobilityId": "7fc99a2b1933433c", "scanner": "scanner-primary", "fingerprint": "ecff7adaaf42df60", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-80e7908659b71d45", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 platform/public/admin/assets/cytoscape.esm-BHYC38rz.js:4"}, "properties": {"repobilityId": "047381e71d5bddcd", "scanner": "scanner-primary", "fingerprint": "80e7908659b71d45", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-61e76c86998e1ad3", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in patch_broll.py:111"}, "properties": {"repobilityId": "51579518fdeeb791", "scanner": "scanner-primary", "fingerprint": "61e76c86998e1ad3", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "patch_broll.py"}, "region": {"startLine": 111}}}]}, {"ruleId": "scanner-8df8369eb73b6fb8", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in platform/apps/admin/src/pages/SessionDetail.jsx:106"}, "properties": {"repobilityId": "f3a42c90087c829a", "scanner": "scanner-primary", "fingerprint": "8df8369eb73b6fb8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/admin/src/pages/SessionDetail.jsx"}, "region": {"startLine": 106}}}]}, {"ruleId": "scanner-7182caed700578b8", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in platform/apps/notebooklm-service/app.py:32"}, "properties": {"repobilityId": "732ee5aa1a997754", "scanner": "scanner-primary", "fingerprint": "7182caed700578b8", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/notebooklm-service/app.py"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-54f7efdad0041597", "level": "note", "message": {"text": "Very large file: platform/apps/api/src/services/testSession.js (2566 lines)"}, "properties": {"repobilityId": "3bb4092290663b8c", "scanner": "scanner-primary", "fingerprint": "54f7efdad0041597", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-0745d57c8f3b3f33", "level": "note", "message": {"text": "Very large file: platform/apps/api/src/services/platformBotHandler.js (1137 lines)"}, "properties": {"repobilityId": "374447aac6fcf78a", "scanner": "scanner-primary", "fingerprint": "0745d57c8f3b3f33", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-c2385526d6fa5ba5", "level": "note", "message": {"text": "Very large file: platform/apps/admin/src/components/funnel/NodeEditor.jsx (1254 lines)"}, "properties": {"repobilityId": "c624d8d898fe2a8e", "scanner": "scanner-primary", "fingerprint": "c2385526d6fa5ba5", "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": "ed2bb4bf8c1d0d2c", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-64782e83a6956733", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/apps/api/package.json"}, "properties": {"repobilityId": "ed1bc9fa00174301", "scanner": "scanner-primary", "fingerprint": "64782e83a6956733", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/api/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-78ceaf18105e9f7c", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/apps/mcp/package.json"}, "properties": {"repobilityId": "7a95aa2ff42245dc", "scanner": "scanner-primary", "fingerprint": "78ceaf18105e9f7c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/mcp/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-cdf2f9aec52fe9de", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/apps/worker/package.json"}, "properties": {"repobilityId": "88f9eb7a7b5224a6", "scanner": "scanner-primary", "fingerprint": "cdf2f9aec52fe9de", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/worker/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5e18ab7e321219f2", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/apps/admin/package.json"}, "properties": {"repobilityId": "d84534b2ee4f8ece", "scanner": "scanner-primary", "fingerprint": "5e18ab7e321219f2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/admin/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d34a870078a45165", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/packages/telegram/package.json"}, "properties": {"repobilityId": "06c83af5f795201e", "scanner": "scanner-primary", "fingerprint": "d34a870078a45165", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/packages/telegram/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ced2cb723ad14fd9", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/packages/logger/package.json"}, "properties": {"repobilityId": "5a839441c8b86692", "scanner": "scanner-primary", "fingerprint": "ced2cb723ad14fd9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/packages/logger/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-afce13803410da02", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/packages/db/package.json"}, "properties": {"repobilityId": "24ea3e28e40e6cd5", "scanner": "scanner-primary", "fingerprint": "afce13803410da02", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/packages/db/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f7688065d956ec24", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/packages/claude/package.json"}, "properties": {"repobilityId": "19cb5b6bf5d2521a", "scanner": "scanner-primary", "fingerprint": "f7688065d956ec24", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/packages/claude/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-80e1a576842b4542", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: platform/packages/storage/package.json"}, "properties": {"repobilityId": "161d97d3bca38635", "scanner": "scanner-primary", "fingerprint": "80e1a576842b4542", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/packages/storage/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "8658419539864b6b", "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": "2e5d45d9d71cc860", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-9d79c4077342a7d0", "level": "warning", "message": {"text": "Runtime service client appears to use placeholder configuration"}, "properties": {"repobilityId": "861ae2fefb71e349", "scanner": "scanner-primary", "fingerprint": "9d79c4077342a7d0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "runtime-config", "service-client", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "ed15c5285baece70", "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": "0efc80a0887dbdf1", "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": "c55ff9b769dd8441", "scanner": "scanner-primary", "fingerprint": "749d4bc1bd66df5f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "9b14747ab8821d08", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "6cd0c511286ca275", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-ed0ab2b088bd7b72", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: platform/CLAUDE.md"}, "properties": {"repobilityId": "62491b3e8712ff4c", "scanner": "scanner-primary", "fingerprint": "ed0ab2b088bd7b72", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/CLAUDE.md"}, "region": {"startLine": 200}}}]}, {"ruleId": "scanner-4525b0020032bf29", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: platform/CLAUDE.md"}, "properties": {"repobilityId": "9bef281f0f159612", "scanner": "scanner-primary", "fingerprint": "4525b0020032bf29", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b278c8c8a21249b8", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in setup_loadfile_nodes.js:17"}, "properties": {"repobilityId": "be94054f9ef38cb2", "scanner": "scanner-primary", "fingerprint": "b278c8c8a21249b8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-846cce7046dd651c", "level": "none", "message": {"text": "Commented-code block (7 lines) in fix-edges-all.js:18"}, "properties": {"repobilityId": "050330f62d6403f2", "scanner": "scanner-primary", "fingerprint": "846cce7046dd651c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5f0297383a5ea9f7", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/constants.js:8"}, "properties": {"repobilityId": "e611707d94263d46", "scanner": "scanner-primary", "fingerprint": "5f0297383a5ea9f7", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-dac81005fa2b7354", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/config/prerequisites.js:18"}, "properties": {"repobilityId": "441b90db51b7d4ee", "scanner": "scanner-primary", "fingerprint": "dac81005fa2b7354", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-bf6b6380e29ce180", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-5-3-balance-process/bot.config.js:8"}, "properties": {"repobilityId": "8fc63ed3cd265d08", "scanner": "scanner-primary", "fingerprint": "bf6b6380e29ce180", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-669919988e2924fd", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-5-3-balance-process/index.js:22"}, "properties": {"repobilityId": "424500ee6e2b24d7", "scanner": "scanner-primary", "fingerprint": "669919988e2924fd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f8c8e438ccc7e98d", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-5-team-instructions/bot.config.js:8"}, "properties": {"repobilityId": "43b0d5a9c26ebd31", "scanner": "scanner-primary", "fingerprint": "f8c8e438ccc7e98d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-210059e5c2135fce", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-5-team-instructions/index.js:19"}, "properties": {"repobilityId": "76a40001f5e24a9e", "scanner": "scanner-primary", "fingerprint": "210059e5c2135fce", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-68c65c42a52c0f6c", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-1-process-update/bot.config.js:9"}, "properties": {"repobilityId": "9ddbfae3c79cd5e7", "scanner": "scanner-primary", "fingerprint": "68c65c42a52c0f6c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-c768e328fb24b3f4", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/projects/finance-course/bots/bot-4-1-process-update/index.js:128"}, "properties": {"repobilityId": "c5b153ca395977b5", "scanner": "scanner-primary", "fingerprint": "c768e328fb24b3f4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-55ce80b7e0c35520", "level": "none", "message": {"text": "Commented-code block (8 lines) in platform/apps/api/src/routes/webhook.js:166"}, "properties": {"repobilityId": "53c8d4e3e98c6b75", "scanner": "scanner-primary", "fingerprint": "55ce80b7e0c35520", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4a6da9777eabe396", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/routes/webhook.js:197"}, "properties": {"repobilityId": "9f15f0d4e756b2ef", "scanner": "scanner-primary", "fingerprint": "4a6da9777eabe396", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-348321f49659bdfa", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/api/src/routes/sessions.js:489"}, "properties": {"repobilityId": "7d61bc8ad2f901f7", "scanner": "scanner-primary", "fingerprint": "348321f49659bdfa", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a8079efb4a149f8f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/routes/sessions.js:362"}, "properties": {"repobilityId": "8f6a0e34e39db9c1", "scanner": "scanner-primary", "fingerprint": "a8079efb4a149f8f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8fd203c80b38c391", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/api/src/services/testSession.js:35"}, "properties": {"repobilityId": "6dbd84c09cd08dd1", "scanner": "scanner-primary", "fingerprint": "8fd203c80b38c391", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-6cb3b66dcd7d4d28", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/testSession.js:982"}, "properties": {"repobilityId": "28c4df69738b6748", "scanner": "scanner-primary", "fingerprint": "6cb3b66dcd7d4d28", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8b3373bcf54eb498", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/channelSync.js:112"}, "properties": {"repobilityId": "98f8d1eb9eae5102", "scanner": "scanner-primary", "fingerprint": "8b3373bcf54eb498", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c175d0329dc6e513", "level": "none", "message": {"text": "Commented-code block (5 lines) in platform/apps/api/src/services/platformBotHandler.js:445"}, "properties": {"repobilityId": "939216e55f80da3f", "scanner": "scanner-primary", "fingerprint": "c175d0329dc6e513", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2880838df8e30af9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/api/src/services/platformBotHandler.js:257"}, "properties": {"repobilityId": "03edd77c36905673", "scanner": "scanner-primary", "fingerprint": "2880838df8e30af9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-dc8ac58afd76cb9e", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/mcp/src/tools-debug.js:189"}, "properties": {"repobilityId": "fa1ce01883b50ad5", "scanner": "scanner-primary", "fingerprint": "dc8ac58afd76cb9e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8b6be8224bf1b0b1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/worker/src/index.js:368"}, "properties": {"repobilityId": "76bfee0bc8194016", "scanner": "scanner-primary", "fingerprint": "8b6be8224bf1b0b1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0712ff81817b472a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/apps/admin/src/api/client.js:18"}, "properties": {"repobilityId": "287d09fba19309b1", "scanner": "scanner-primary", "fingerprint": "0712ff81817b472a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-082ede8017f5e946", "level": "note", "message": {"text": "Legacy-named symbol `business_process_v2` in platform/apps/admin/src/components/funnel/NodeEditor.jsx:849"}, "properties": {"repobilityId": "ee31ae1862587eda", "scanner": "scanner-primary", "fingerprint": "082ede8017f5e946", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f04f2c6524ac08db", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/scripts/run_full_regression.js:17"}, "properties": {"repobilityId": "8e7d7a04e73e77f1", "scanner": "scanner-primary", "fingerprint": "f04f2c6524ac08db", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9ecbc993bdea7c71", "level": "note", "message": {"text": "Legacy-named symbol `loadfile_business_process_v2` in platform/scripts/apply_flow_updates.js:17"}, "properties": {"repobilityId": "74ea463ec2154b55", "scanner": "scanner-primary", "fingerprint": "9ecbc993bdea7c71", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8061ca5cd3c67d44", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/packages/claude/src/wrapper.js:232"}, "properties": {"repobilityId": "950bd85093d81608", "scanner": "scanner-primary", "fingerprint": "8061ca5cd3c67d44", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-239ac40dfceb846d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 platform/public/admin/assets/katex-C5jXJg4s.js:252"}, "properties": {"repobilityId": "392365b0dbbe1a46", "scanner": "scanner-primary", "fingerprint": "239ac40dfceb846d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-100b6131f2533e8c", "level": "note", "message": {"text": "Legacy-named symbol `AsOld` in platform/public/admin/assets/wardley-L42UT6IY-CB-pqIph.js:5"}, "properties": {"repobilityId": "44e069f0380125a5", "scanner": "scanner-primary", "fingerprint": "100b6131f2533e8c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-b0b7578dd2a289b6", "level": "note", "message": {"text": "26 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "8099a5c5713d37b9", "scanner": "scanner-primary", "fingerprint": "b0b7578dd2a289b6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-2c04133e54348533", "level": "note", "message": {"text": "Near-duplicate function bodies in 2 places"}, "properties": {"repobilityId": "6edc7dcbb4560e65", "scanner": "scanner-primary", "fingerprint": "2c04133e54348533", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "duplicate", "dry"]}}, {"ruleId": "scanner-8da4c54b95599f2d", "level": "warning", "message": {"text": "Frontend route `/funnel/:botId` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "ea3e92feae84f97d", "scanner": "scanner-primary", "fingerprint": "8da4c54b95599f2d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-10af588423c792be", "level": "warning", "message": {"text": "Frontend route `/funnel/:botId/analytics` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "4a61cea41f516eb4", "scanner": "scanner-primary", "fingerprint": "10af588423c792be", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-cd2c3a6086676159", "level": "warning", "message": {"text": "Frontend route `funnels` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "71778db442286890", "scanner": "scanner-primary", "fingerprint": "cd2c3a6086676159", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c9ca7442d19c4d2a", "level": "warning", "message": {"text": "Frontend route `projects` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "aade18360aa4e1ab", "scanner": "scanner-primary", "fingerprint": "c9ca7442d19c4d2a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-f156f1c736641ff3", "level": "warning", "message": {"text": "Frontend route `dashboard` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "0a5768669b0da1ff", "scanner": "scanner-primary", "fingerprint": "f156f1c736641ff3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3ee247854b670a2f", "level": "warning", "message": {"text": "Frontend route `content` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "cff25f8504abe322", "scanner": "scanner-primary", "fingerprint": "3ee247854b670a2f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-f7ef41dc4eeab520", "level": "warning", "message": {"text": "Frontend route `broadcasts` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "fff83fa23a58caae", "scanner": "scanner-primary", "fingerprint": "f7ef41dc4eeab520", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-30245c7168c2a2ab", "level": "warning", "message": {"text": "Frontend route `connectors` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "a2080c95d75f6d94", "scanner": "scanner-primary", "fingerprint": "30245c7168c2a2ab", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3f97e65bc59abd33", "level": "warning", "message": {"text": "Frontend route `bots` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "d4dafd9ccd9f4369", "scanner": "scanner-primary", "fingerprint": "3f97e65bc59abd33", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-455d704d01da2c24", "level": "warning", "message": {"text": "Frontend route `bots/:botId/sessions` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "e4307cc5fc4b6296", "scanner": "scanner-primary", "fingerprint": "455d704d01da2c24", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9e4971a43c48f47b", "level": "warning", "message": {"text": "Frontend route `sessions` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "705094d187db7dff", "scanner": "scanner-primary", "fingerprint": "9e4971a43c48f47b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-c832e7b69ecf85bb", "level": "warning", "message": {"text": "Frontend route `sessions/:id` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "8fc7f9fda71904eb", "scanner": "scanner-primary", "fingerprint": "c832e7b69ecf85bb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-64262fb7d8f3d85e", "level": "warning", "message": {"text": "Frontend route `users` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "a1a6900590099336", "scanner": "scanner-primary", "fingerprint": "64262fb7d8f3d85e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-8284781fbb7f6123", "level": "warning", "message": {"text": "Frontend route `subscribers` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "c686d4077e496f07", "scanner": "scanner-primary", "fingerprint": "8284781fbb7f6123", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-47a9c4b3491eb404", "level": "warning", "message": {"text": "Frontend route `users/:id` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "b8ee43586e1fdbd9", "scanner": "scanner-primary", "fingerprint": "47a9c4b3491eb404", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-725bc93719b54b56", "level": "warning", "message": {"text": "Frontend route `subscribers/:id` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "e1828cbe5fc1b36a", "scanner": "scanner-primary", "fingerprint": "725bc93719b54b56", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9afb9f293393889e", "level": "warning", "message": {"text": "Frontend route `api-logs` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "8a8277e49e115620", "scanner": "scanner-primary", "fingerprint": "9afb9f293393889e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-a73ca485a68a0d74", "level": "warning", "message": {"text": "Frontend route `errors` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "6f41733c5c26bf3a", "scanner": "scanner-primary", "fingerprint": "a73ca485a68a0d74", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-161249ba0c4ba03c", "level": "warning", "message": {"text": "Frontend route `logs` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "66480c5f9a0128b5", "scanner": "scanner-primary", "fingerprint": "161249ba0c4ba03c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-e9bde4790a075778", "level": "warning", "message": {"text": "Frontend route `settings` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "07aa7bae20306b8c", "scanner": "scanner-primary", "fingerprint": "e9bde4790a075778", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-8e4a72114ccb2b63", "level": "warning", "message": {"text": "Frontend route `mcp` has no Link/navigate to it \u2014 platform/apps/admin/src/App.jsx"}, "properties": {"repobilityId": "f4623152b2ba12d6", "scanner": "scanner-primary", "fingerprint": "8e4a72114ccb2b63", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-625e6bffe3ce8ff1", "level": "error", "message": {"text": "FastAPI POST `create_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:81"}, "properties": {"repobilityId": "1ec9b7ea365ffa16", "scanner": "scanner-primary", "fingerprint": "625e6bffe3ce8ff1", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/notebooklm-service/app.py"}, "region": {"startLine": 81}}}]}, {"ruleId": "scanner-11b8a7be702c0f06", "level": "error", "message": {"text": "FastAPI POST `add_source` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:97"}, "properties": {"repobilityId": "beeb534e15d2b68b", "scanner": "scanner-primary", "fingerprint": "11b8a7be702c0f06", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/notebooklm-service/app.py"}, "region": {"startLine": 97}}}]}, {"ruleId": "scanner-52cedebd475bf782", "level": "error", "message": {"text": "FastAPI POST `query_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:134"}, "properties": {"repobilityId": "6da53ec622dd0472", "scanner": "scanner-primary", "fingerprint": "52cedebd475bf782", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/notebooklm-service/app.py"}, "region": {"startLine": 134}}}]}, {"ruleId": "scanner-ea589753bbc2d98d", "level": "error", "message": {"text": "FastAPI DELETE `delete_notebook` without auth dependency \u2014 platform/apps/notebooklm-service/app.py:168"}, "properties": {"repobilityId": "24e381505edfd5e0", "scanner": "scanner-primary", "fingerprint": "ea589753bbc2d98d", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "platform/apps/notebooklm-service/app.py"}, "region": {"startLine": 168}}}]}, {"ruleId": "scanner-fbd6be88f702982f", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/file/bot${token}/${filePath} (platform/apps/api/src/routes/sessions.js:373)"}, "properties": {"repobilityId": "81fecc37ac1c2463", "scanner": "scanner-primary", "fingerprint": "fbd6be88f702982f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-33bc755d6ac1bb5b", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/editMessageText (platform/apps/api/src/routes/sessions.js:558)"}, "properties": {"repobilityId": "6de479d0d37054d2", "scanner": "scanner-primary", "fingerprint": "33bc755d6ac1bb5b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-81d7642cc520991a", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/deleteMessage (platform/apps/api/src/routes/sessions.js:599)"}, "properties": {"repobilityId": "14f5b035910f962d", "scanner": "scanner-primary", "fingerprint": "81d7642cc520991a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8022b9eccb9a7e0b", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${notifyToken}/sendMessage (platform/apps/api/src/services/testSession.js:1836)"}, "properties": {"repobilityId": "0af599a232437374", "scanner": "scanner-primary", "fingerprint": "8022b9eccb9a7e0b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-bc3d95586723b744", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getMe (platform/apps/api/src/services/channelSync.js:61)"}, "properties": {"repobilityId": "1519c50c2d53a071", "scanner": "scanner-primary", "fingerprint": "bc3d95586723b744", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-43154d03cfbdc38f", "level": "error", "message": {"text": "Dangling fetch: POST https://api.telegram.org/bot${token}/setWebhook (platform/apps/api/src/services/channelSync.js:112)"}, "properties": {"repobilityId": "d50cbdb60ede57cf", "scanner": "scanner-primary", "fingerprint": "43154d03cfbdc38f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-79638788a3bd1aef", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getWebhookInfo (platform/apps/api/src/services/channelSync.js:123)"}, "properties": {"repobilityId": "6f87eab2d89d5c31", "scanner": "scanner-primary", "fingerprint": "79638788a3bd1aef", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-408cfe2546b07dc0", "level": "error", "message": {"text": "Dangling fetch: POST https://graph.facebook.com/v23.0/${appId}/subscriptions (platform/apps/api/src/services/channelSync.js:159)"}, "properties": {"repobilityId": "1c66cacc7e4da87e", "scanner": "scanner-primary", "fingerprint": "408cfe2546b07dc0", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e18ac300b470a2bb", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId} (platform/apps/api/src/services/platformBotHandler.js:159)"}, "properties": {"repobilityId": "95671e2f2f13bac2", "scanner": "scanner-primary", "fingerprint": "e18ac300b470a2bb", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7b320767c4f1e28a", "level": "error", "message": {"text": "Dangling fetch: POST https://api.openai.com/v1/audio/transcriptions (platform/apps/api/src/services/platformBotHandler.js:223)"}, "properties": {"repobilityId": "b56d8309919443cd", "scanner": "scanner-primary", "fingerprint": "7b320767c4f1e28a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3e73ee9cd1385bae", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getUserProfilePhotos?user_id=${telegramId}&limit=1 (platform/apps/api/src/services/platformBotHandler.js:246)"}, "properties": {"repobilityId": "677cc4f35b2b3814", "scanner": "scanner-primary", "fingerprint": "3e73ee9cd1385bae", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-4eed8703e74280ec", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token}/getFile?file_id=${fileId} (platform/apps/api/src/services/platformBotHandler.js:257)"}, "properties": {"repobilityId": "1594123a54946426", "scanner": "scanner-primary", "fingerprint": "4eed8703e74280ec", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-5fd5941af6d3e801", "level": "error", "message": {"text": "Dangling fetch: GET /api/users/${userId}/photo (platform/apps/admin/src/components/UserPhoto.jsx:20)"}, "properties": {"repobilityId": "59ce1f20ef01f0f0", "scanner": "scanner-primary", "fingerprint": "5fd5941af6d3e801", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-20f9e0beb36e98df", "level": "error", "message": {"text": "Dangling fetch: GET /api/users/${userId}/photo (platform/apps/admin/src/components/UserPhoto.jsx:77)"}, "properties": {"repobilityId": "7fe6736b73f56236", "scanner": "scanner-primary", "fingerprint": "20f9e0beb36e98df", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9846457ba1a3a2e4", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${String(token).trim()}/getMe (platform/apps/admin/src/components/funnel/EnvironmentPanel.jsx:259)"}, "properties": {"repobilityId": "49bca6cf721168ea", "scanner": "scanner-primary", "fingerprint": "9846457ba1a3a2e4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c798ec39f4c39554", "level": "error", "message": {"text": "Dangling fetch: GET https://api.telegram.org/bot${token.trim()}/getMe (platform/apps/admin/src/pages/Connectors.jsx:7)"}, "properties": {"repobilityId": "7efd6cafcf9ea1ce", "scanner": "scanner-primary", "fingerprint": "c798ec39f4c39554", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7f01f61e6096ac8b", "level": "error", "message": {"text": "Dangling fetch: POST https://api.openai.com/v1/chat/completions (platform/packages/claude/src/wrapper.js:232)"}, "properties": {"repobilityId": "79dbe8c8999b15bb", "scanner": "scanner-primary", "fingerprint": "7f01f61e6096ac8b", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-00f7772acd4236ed", "level": "note", "message": {"text": "Unused endpoint: GET /notebooks"}, "properties": {"repobilityId": "056e343d55978405", "scanner": "scanner-primary", "fingerprint": "00f7772acd4236ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f22375709e28e8b0", "level": "note", "message": {"text": "Unused endpoint: POST /notebooks"}, "properties": {"repobilityId": "1dc9561ca4eb76e0", "scanner": "scanner-primary", "fingerprint": "f22375709e28e8b0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3be10e2bd7df86b3", "level": "note", "message": {"text": "Unused endpoint: POST /notebooks/{notebook_id}/sources"}, "properties": {"repobilityId": "0fe387c1dd5fd312", "scanner": "scanner-primary", "fingerprint": "3be10e2bd7df86b3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7d6331595dbb2791", "level": "note", "message": {"text": "Unused endpoint: POST /notebooks/{notebook_id}/query"}, "properties": {"repobilityId": "22d2cfd04fce26a7", "scanner": "scanner-primary", "fingerprint": "7d6331595dbb2791", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dfd336506aa5e6df", "level": "note", "message": {"text": "Unused endpoint: DELETE /notebooks/{notebook_id}"}, "properties": {"repobilityId": "b7c410bfad78f540", "scanner": "scanner-primary", "fingerprint": "dfd336506aa5e6df", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dee3a0ace2bb985c", "level": "note", "message": {"text": "Unused endpoint: USE /bot-files"}, "properties": {"repobilityId": "b5d86345ec143ef2", "scanner": "scanner-primary", "fingerprint": "dee3a0ace2bb985c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e7249f2f256161b5", "level": "note", "message": {"text": "Unused endpoint: USE /webhook"}, "properties": {"repobilityId": "5fe2817c8adb246a", "scanner": "scanner-primary", "fingerprint": "e7249f2f256161b5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-728e92394c568abf", "level": "note", "message": {"text": "Unused endpoint: USE /api/projects"}, "properties": {"repobilityId": "a780a88b6e3ba1e0", "scanner": "scanner-primary", "fingerprint": "728e92394c568abf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ab7438d173aea4ec", "level": "note", "message": {"text": "Unused endpoint: USE /api/bots"}, "properties": {"repobilityId": "a53f3843c9b42426", "scanner": "scanner-primary", "fingerprint": "ab7438d173aea4ec", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8636dd48e48d1da9", "level": "note", "message": {"text": "Unused endpoint: USE /api/sessions"}, "properties": {"repobilityId": "4572c4dd92d6ce73", "scanner": "scanner-primary", "fingerprint": "8636dd48e48d1da9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4ff40cb10f7c8519", "level": "note", "message": {"text": "Unused endpoint: USE /api/users"}, "properties": {"repobilityId": "f1e6e380e1cf7a5b", "scanner": "scanner-primary", "fingerprint": "4ff40cb10f7c8519", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-013e0d7c58374e34", "level": "note", "message": {"text": "Unused endpoint: USE /api/funnels"}, "properties": {"repobilityId": "98e6566753db4f79", "scanner": "scanner-primary", "fingerprint": "013e0d7c58374e34", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2a48048f3c793de1", "level": "note", "message": {"text": "Unused endpoint: USE /api/connectors"}, "properties": {"repobilityId": "7fa78309d40cc651", "scanner": "scanner-primary", "fingerprint": "2a48048f3c793de1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-32ee27e9f9ae5691", "level": "note", "message": {"text": "Unused endpoint: USE /api/saved-connectors"}, "properties": {"repobilityId": "9ea54610aef1b42b", "scanner": "scanner-primary", "fingerprint": "32ee27e9f9ae5691", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-38a323166190b71a", "level": "note", "message": {"text": "Unused endpoint: USE /api/system-keys"}, "properties": {"repobilityId": "d9848c6f697be50b", "scanner": "scanner-primary", "fingerprint": "38a323166190b71a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d93a530ce10d47d9", "level": "note", "message": {"text": "Unused endpoint: USE /api/admin"}, "properties": {"repobilityId": "02aaa2cb861483e4", "scanner": "scanner-primary", "fingerprint": "d93a530ce10d47d9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-da48c098aa00614d", "level": "note", "message": {"text": "Unused endpoint: USE /api/broadcasts"}, "properties": {"repobilityId": "526b87e0b99966d5", "scanner": "scanner-primary", "fingerprint": "da48c098aa00614d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4df67aa27a99eee8", "level": "note", "message": {"text": "Unused endpoint: USE /api/mcp"}, "properties": {"repobilityId": "21d4e13615f21a80", "scanner": "scanner-primary", "fingerprint": "4df67aa27a99eee8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-501f87ebb8050563", "level": "note", "message": {"text": "Unused endpoint: USE /api/mcp-edit"}, "properties": {"repobilityId": "c6d7978b273ccf37", "scanner": "scanner-primary", "fingerprint": "501f87ebb8050563", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-903c59692f77f6ff", "level": "note", "message": {"text": "Unused endpoint: USE /api/mcp-debug"}, "properties": {"repobilityId": "c72ed9a775977606", "scanner": "scanner-primary", "fingerprint": "903c59692f77f6ff", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-95e266019920938e", "level": "note", "message": {"text": "Unused endpoint: USE /mcp"}, "properties": {"repobilityId": "7a7c7b813f025e97", "scanner": "scanner-primary", "fingerprint": "95e266019920938e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ca5756175765b49d", "level": "note", "message": {"text": "Unused endpoint: GET /:id"}, "properties": {"repobilityId": "669c8ee8dc48dcb5", "scanner": "scanner-primary", "fingerprint": "ca5756175765b49d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-18bd2efa3e17ad5c", "level": "note", "message": {"text": "Unused endpoint: GET /:botId"}, "properties": {"repobilityId": "fbe80d014bba82d0", "scanner": "scanner-primary", "fingerprint": "18bd2efa3e17ad5c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-adfb2700a5fba328", "level": "note", "message": {"text": "Unused endpoint: PUT /:botId"}, "properties": {"repobilityId": "0aa173ccaec7261a", "scanner": "scanner-primary", "fingerprint": "adfb2700a5fba328", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-18f74cd9e71e19ab", "level": "note", "message": {"text": "Unused endpoint: GET /:botId/export"}, "properties": {"repobilityId": "93c5ece42a82bcc1", "scanner": "scanner-primary", "fingerprint": "18f74cd9e71e19ab", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c82be50d3bc695b8", "level": "note", "message": {"text": "Unused endpoint: POST /:botId/import"}, "properties": {"repobilityId": "d80502da50c0ef0a", "scanner": "scanner-primary", "fingerprint": "c82be50d3bc695b8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5e8f3bdc9229c562", "level": "note", "message": {"text": "Unused endpoint: GET /:botId/keys"}, "properties": {"repobilityId": "64c901ca88ca3736", "scanner": "scanner-primary", "fingerprint": "5e8f3bdc9229c562", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a919ad0b285e0e7b", "level": "note", "message": {"text": "Unused endpoint: PUT /:botId/keys"}, "properties": {"repobilityId": "55e148106f4349f3", "scanner": "scanner-primary", "fingerprint": "a919ad0b285e0e7b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-672399cc8bfb85d4", "level": "note", "message": {"text": "Unused endpoint: DELETE /:botId/keys/:key"}, "properties": {"repobilityId": "70033ca4096f4dd0", "scanner": "scanner-primary", "fingerprint": "672399cc8bfb85d4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-98454545203f7f37", "level": "note", "message": {"text": "Unused endpoint: POST /:botId/homework-done"}, "properties": {"repobilityId": "4bb3cd4f6727d94d", "scanner": "scanner-primary", "fingerprint": "98454545203f7f37", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d388fb2d9975eef2", "level": "note", "message": {"text": "Unused endpoint: POST /:botId/sync-channels"}, "properties": {"repobilityId": "a3afa5baaf21c0bd", "scanner": "scanner-primary", "fingerprint": "d388fb2d9975eef2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-105e263aa7f10c1a", "level": "note", "message": {"text": "Unused endpoint: GET /:botId/keys/:key/reveal"}, "properties": {"repobilityId": "d5f97f5a27c1879c", "scanner": "scanner-primary", "fingerprint": "105e263aa7f10c1a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8dc44bdc90f89fbc", "level": "note", "message": {"text": "Unused endpoint: POST /:botId/edges"}, "properties": {"repobilityId": "88e1698270fd8746", "scanner": "scanner-primary", "fingerprint": "8dc44bdc90f89fbc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ec0380c2532605fc", "level": "note", "message": {"text": "Unused endpoint: PUT /:botId/edges"}, "properties": {"repobilityId": "71bfb0c33b0f899d", "scanner": "scanner-primary", "fingerprint": "ec0380c2532605fc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5cceca3f6bdb2261", "level": "note", "message": {"text": "Unused endpoint: DELETE /:botId/edges/:edgeId"}, "properties": {"repobilityId": "36e3abfb947eaf5a", "scanner": "scanner-primary", "fingerprint": "5cceca3f6bdb2261", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3962ff42a429cffe", "level": "note", "message": {"text": "Unused endpoint: GET /:botId/nodes/:nodeId/stats"}, "properties": {"repobilityId": "c7a53a8979fa7fcf", "scanner": "scanner-primary", "fingerprint": "3962ff42a429cffe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2a68b47955264fff", "level": "note", "message": {"text": "Unused endpoint: GET /:botId/analytics"}, "properties": {"repobilityId": "51fa4fb4c656bcaa", "scanner": "scanner-primary", "fingerprint": "2a68b47955264fff", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3087f0b79caed3dd", "level": "note", "message": {"text": "Unused endpoint: POST /:botId/check-prerequisites"}, "properties": {"repobilityId": "a056dcb5f5cbb8f4", "scanner": "scanner-primary", "fingerprint": "3087f0b79caed3dd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-89fd5687e7760b60", "level": "note", "message": {"text": "Unused endpoint: POST /:botId/upload-file"}, "properties": {"repobilityId": "1bbc90ab9d6e547b", "scanner": "scanner-primary", "fingerprint": "89fd5687e7760b60", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-618721b912bad1c2", "level": "note", "message": {"text": "Unused endpoint: POST /login"}, "properties": {"repobilityId": "f4e8494869da2260", "scanner": "scanner-primary", "fingerprint": "618721b912bad1c2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99fc36db98c134ce", "level": "note", "message": {"text": "Unused endpoint: POST /logout"}, "properties": {"repobilityId": "7e9c70b32370d53a", "scanner": "scanner-primary", "fingerprint": "99fc36db98c134ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4629fc2f2a182ac9", "level": "note", "message": {"text": "Unused endpoint: GET /analytics"}, "properties": {"repobilityId": "713bd8355f8084be", "scanner": "scanner-primary", "fingerprint": "4629fc2f2a182ac9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1515654f1d0fdbfe", "level": "note", "message": {"text": "Unused endpoint: GET /errors"}, "properties": {"repobilityId": "745c778b5a7f6d41", "scanner": "scanner-primary", "fingerprint": "1515654f1d0fdbfe", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2d00fdf5ded225e6", "level": "note", "message": {"text": "Unused endpoint: PATCH /errors/:id/resolve"}, "properties": {"repobilityId": "010281d57cf2edef", "scanner": "scanner-primary", "fingerprint": "2d00fdf5ded225e6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0509c1631f349a45", "level": "note", "message": {"text": "Unused endpoint: GET /sessions/unread-count"}, "properties": {"repobilityId": "dfe0ed468842cd65", "scanner": "scanner-primary", "fingerprint": "0509c1631f349a45", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b15d518d538de57d", "level": "note", "message": {"text": "Unused endpoint: GET /sessions"}, "properties": {"repobilityId": "92fbded663967248", "scanner": "scanner-primary", "fingerprint": "b15d518d538de57d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1308d862172c711d", "level": "note", "message": {"text": "Unused endpoint: GET /api-logs"}, "properties": {"repobilityId": "7643b6144bee8b70", "scanner": "scanner-primary", "fingerprint": "1308d862172c711d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2f34bb57423f5a53", "level": "note", "message": {"text": "Unused endpoint: POST /bots/:id/run-regression"}, "properties": {"repobilityId": "efb21e30e9a3d43d", "scanner": "scanner-primary", "fingerprint": "2f34bb57423f5a53", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ecc204cf90867770", "level": "note", "message": {"text": "Unused endpoint: POST /bots/:id/webhook-test"}, "properties": {"repobilityId": "a34b83856d1181f0", "scanner": "scanner-primary", "fingerprint": "ecc204cf90867770", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1abca45c20ef4632", "level": "note", "message": {"text": "Unused endpoint: POST /projects/:slug/run-regressions"}, "properties": {"repobilityId": "c06abee4c18a807a", "scanner": "scanner-primary", "fingerprint": "1abca45c20ef4632", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}