{"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-bead75b0f9233e05", "name": "No API endpoints detected", "shortDescription": {"text": "No API endpoints detected"}, "fullDescription": {"text": "The scanner did not find FastAPI/Flask/Express/NestJS/GraphQL/gRPC routes. If this repo exposes APIs, the framework may be unsupported."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2dadaca996bfd872", "name": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-orphaned-recurrence.ts:28", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-orphaned-recurrence.ts:28"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-602c2012c6fc79af", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-recurrence.ts:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-recurrence.ts:9"}, "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-01d46ad14f59361b", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ActivityFeed.tsx:169", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ActivityFeed.tsx:169"}, "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-f8381ce1b55587cc", "name": "`truncate` class without `title=` for hover reveal \u2014 components/RecurringTasksPanel.tsx:150", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/RecurringTasksPanel.tsx:150"}, "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-369bb488401bcd2c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/DependenciesSection.tsx:219", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/DependenciesSection.tsx:219"}, "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-8b2390d58ef2aa94", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ArchiveManager.tsx:102", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ArchiveManager.tsx:102"}, "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-6ebee2b6f1221ca7", "name": "`truncate` class without `title=` for hover reveal \u2014 components/DuplicateToProjectsModal.tsx:74", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/DuplicateToProjectsModal.tsx:74"}, "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-f684b6d3d0cc87f8", "name": "`truncate` class without `title=` for hover reveal \u2014 components/BulkActionsToolbar.tsx:213", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/BulkActionsToolbar.tsx:213"}, "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-3be898c5a1bef50f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/SettingsModal.tsx:433", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/SettingsModal.tsx:433"}, "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-0116dc14339516d5", "name": "`truncate` class without `title=` for hover reveal \u2014 components/TaskRelatedItems.tsx:78", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/TaskRelatedItems.tsx:78"}, "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-3aa257cf23a09ce3", "name": "`truncate` class without `title=` for hover reveal \u2014 components/NavigationRail.tsx:388", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/NavigationRail.tsx:388"}, "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-7072c5f8e89a7099", "name": "`truncate` class without `title=` for hover reveal \u2014 components/KanbanBoard.tsx:951", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/KanbanBoard.tsx:951"}, "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-0ef3967dc295fe47", "name": "`truncate` class without `title=` for hover reveal \u2014 components/AutomationRulesPanel.tsx:144", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AutomationRulesPanel.tsx:144"}, "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-c0edddc03ff4f130", "name": "`truncate` class without `title=` for hover reveal \u2014 components/NotificationBell.tsx:280", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/NotificationBell.tsx:280"}, "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-750bbc139e006bd0", "name": "`truncate` class without `title=` for hover reveal \u2014 components/AttachmentsSection.tsx:311", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AttachmentsSection.tsx:311"}, "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-0c8208d9193029a1", "name": "`truncate` class without `title=` for hover reveal \u2014 components/AddTaskModal.tsx:665", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AddTaskModal.tsx:665"}, "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-f91120d9bec2824f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/ProjectSelector.tsx:195", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ProjectSelector.tsx:195"}, "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-185f86133f9df0da", "name": "`truncate` class without `title=` for hover reveal \u2014 components/CompletedTasksReport.tsx:577", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/CompletedTasksReport.tsx:577"}, "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-0dcaf65b2baae2f3", "name": "`truncate` class without `title=` for hover reveal \u2014 components/FilterBar.tsx:435", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/FilterBar.tsx:435"}, "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-a1acfd8c7dd2ec01", "name": "`truncate` class without `title=` for hover reveal \u2014 components/settings/AccountSettingsView.tsx:411", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/settings/AccountSettingsView.tsx:411"}, "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-aee2fea674437a6c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/settings/SettingsShell.tsx:108", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/settings/SettingsShell.tsx:108"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-47539213df9d3189", "name": "`truncate` class without `title=` for hover reveal \u2014 components/settings/ProjectSettingsView.tsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/settings/ProjectSettingsView.tsx:131"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d57e002476f0f0e2", "name": "`truncate` class without `title=` for hover reveal \u2014 components/auth/AuthShell.tsx:154", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/auth/AuthShell.tsx:154"}, "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-aa3884a6b2a36918", "name": "`truncate` class without `title=` for hover reveal \u2014 components/task/LinkedTab.tsx:60", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/task/LinkedTab.tsx:60"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c0bae82d18b192a8", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 components/toolkit/reports/ReportsPreview.tsx:37", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 components/toolkit/reports/ReportsPreview.tsx:37"}, "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-87a71ff22d69ddaf", "name": "`truncate` class without `title=` for hover reveal \u2014 components/toolkit/reports/ReportsPanel.tsx:334", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/toolkit/reports/ReportsPanel.tsx:334"}, "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-4602075f07183c70", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobilePortfolio.tsx:164", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobilePortfolio.tsx:164"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0b78c25fb8b88cde", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileTaskDetail.tsx:162", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileTaskDetail.tsx:162"}, "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-da797ecba1bdc68f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileProjectBoard.tsx:67", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileProjectBoard.tsx:67"}, "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-8319ecb05df2da1f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileInbox.tsx:164", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileInbox.tsx:164"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ae8110d5dff51213", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileToday.tsx:56", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileToday.tsx:56"}, "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-70f35099d7c222f7", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileProfile.tsx:58", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileProfile.tsx:58"}, "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-f204384d852e8b80", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/VendorManagementView.tsx:393", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/VendorManagementView.tsx:393"}, "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-b3cfc305c834a399", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/ArcReviewDrawer.tsx:186", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/ArcReviewDrawer.tsx:186"}, "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-2693727f52c81dd0", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/BoardMeetingsView.tsx:562", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/BoardMeetingsView.tsx:562"}, "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-ddd422e34cb4f9fe", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/NoticeTemplateView.tsx:166", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/NoticeTemplateView.tsx:166"}, "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-74302c86de6eb1b7", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/InspectionDateWidget.tsx:371", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/InspectionDateWidget.tsx:371"}, "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-6773717dfce89089", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/LienManagementView.tsx:443", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/LienManagementView.tsx:443"}, "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-b33b85225ed26525", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/BoardMemberRegistry.tsx:186", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/BoardMemberRegistry.tsx:186"}, "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-19f20a710a56f65a", "name": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/ArcFilesPanel.tsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/ArcFilesPanel.tsx:131"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f1179b9c2126c452", "name": "`truncate` class without `title=` for hover reveal \u2014 components/runtime/FlowstateRuntime.tsx:2107", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/runtime/FlowstateRuntime.tsx:2107"}, "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-58e3f1677204e376", "name": "`truncate` class without `title=` for hover reveal \u2014 components/notes/NoteBubble.tsx:143", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/notes/NoteBubble.tsx:143"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-077c6ea97205cd52", "name": "`truncate` class without `title=` for hover reveal \u2014 components/pulse/BoardDayRitual.tsx:86", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/pulse/BoardDayRitual.tsx:86"}, "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-f804495970e6882f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/pulse/PortfolioBiPanel.tsx:106", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/pulse/PortfolioBiPanel.tsx:106"}, "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-4f0817fce86d68ab", "name": "`truncate` class without `title=` for hover reveal \u2014 components/record/RecordPeekDrawer.tsx:148", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/RecordPeekDrawer.tsx:148"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ca7dc7f8a9567ffb", "name": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/MeetingPeekPanel.tsx:70", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/MeetingPeekPanel.tsx:70"}, "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-79d268b9dd4e64cb", "name": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/InspectionPeekPanel.tsx:37", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/InspectionPeekPanel.tsx: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-98f88ce27abd998c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/RecordPanelPrimitives.tsx:24", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/RecordPanelPrimitives.tsx:24"}, "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-ae735b05242aae93", "name": "`truncate` class without `title=` for hover reveal \u2014 components/inbox/InboxView.tsx:384", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/inbox/InboxView.tsx:384"}, "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-6f71ee8358be4444", "name": "`truncate` class without `title=` for hover reveal \u2014 components/views/DashboardView.tsx:236", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/views/DashboardView.tsx:236"}, "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-f55aea805746237d", "name": "`truncate` class without `title=` for hover reveal \u2014 components/views/TimelineView.tsx:378", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/views/TimelineView.tsx:378"}, "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-b024b5ad5dfceb68", "name": "`truncate` class without `title=` for hover reveal \u2014 components/views/MyDayView.tsx:394", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/views/MyDayView.tsx:394"}, "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-e57ab0fecf76346d", "name": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/MoreItemsPopover.tsx:75", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/MoreItemsPopover.tsx:75"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b10cc0071eec2366", "name": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarMiniSidebar.tsx:141", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarMiniSidebar.tsx:141"}, "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-c836c984e680a62f", "name": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarQuarterView.tsx:252", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarQuarterView.tsx:252"}, "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-c55dc656c42c63b8", "name": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarFilters.tsx:187", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarFilters.tsx:187"}, "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-b08db60c6c52f617", "name": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarMeetingPopover.tsx:75", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarMeetingPopover.tsx:75"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-805859c20f4941db", "name": "`truncate` class without `title=` for hover reveal \u2014 components/board/BoardSignalShelf.tsx:199", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/board/BoardSignalShelf.tsx:199"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-85a5cd5820c16ba0", "name": "`truncate` class without `title=` for hover reveal \u2014 app/admin/page.tsx:465", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/admin/page.tsx:465"}, "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-e8687cf5807c5dfb", "name": "`truncate` class without `title=` for hover reveal \u2014 app/(app)/settings/notifications/page.tsx:470", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/(app)/settings/notifications/page.tsx:470"}, "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-46e13c94ffe3d79e", "name": "Stray `console.log` in TS/JS \u2014 lib/dev-logger.ts:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 lib/dev-logger.ts:15"}, "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-af86d6b3695cb6af", "name": "Stray `console.log` in TS/JS \u2014 lib/server-logger.ts:49", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 lib/server-logger.ts:49"}, "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-124d78d5053b240b", "name": "Stray `console.log` in TS/JS \u2014 lib/logger.ts:62", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 lib/logger.ts:62"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b46853cb3c6d2574", "name": "Stray `console.log` in TS/JS \u2014 hooks/useInstallPrompt.ts:101", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 hooks/useInstallPrompt.ts:101"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b7c9b0b79da78bbe", "name": "Insecure pattern 'direct_innerhtml_assignment' in __tests__/hooks/use-keyboard-shortcuts.test.tsx:21", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in __tests__/hooks/use-keyboard-shortcuts.test.tsx:21"}, "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-a0c4ed60b6154411", "name": "Insecure pattern 'node_child_process' in mcp/reports/scripts/generate-arc-gif.mjs:30", "shortDescription": {"text": "Insecure pattern 'node_child_process' in mcp/reports/scripts/generate-arc-gif.mjs:30"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-826f62f977030901", "name": "Insecure pattern 'eval_used' in scripts/check-bundle-budgets.mjs:103", "shortDescription": {"text": "Insecure pattern 'eval_used' in scripts/check-bundle-budgets.mjs:103"}, "fullDescription": {"text": "Found a known-risky pattern (eval_used). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-49e8b71c15671695", "name": "Insecure pattern 'direct_innerhtml_assignment' in components/RichTextEditor.tsx:146", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in components/RichTextEditor.tsx:146"}, "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-4a8fdc1fe7ed126d", "name": "Insecure pattern 'domparser_html_parse' in components/RichTextEditor.tsx:27", "shortDescription": {"text": "Insecure pattern 'domparser_html_parse' in components/RichTextEditor.tsx:27"}, "fullDescription": {"text": "Found a known-risky pattern (domparser_html_parse). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c90d6e7be33e2093", "name": "Insecure pattern 'dangerous_innerhtml' in components/toolkit/reports/ReportsPreview.tsx:37", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in components/toolkit/reports/ReportsPreview.tsx:37"}, "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-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d3f51f44744f42ec", "name": "Very large file: types/supabase.generated.ts (2089 lines)", "shortDescription": {"text": "Very large file: types/supabase.generated.ts (2089 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-159ba78fd7540205", "name": "Very large file: components/HelpGuide.tsx (1413 lines)", "shortDescription": {"text": "Very large file: components/HelpGuide.tsx (1413 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-7ad89b77409d6ea6", "name": "Very large file: components/AddTaskModal.tsx (1606 lines)", "shortDescription": {"text": "Very large file: components/AddTaskModal.tsx (1606 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-a2ceea2c409b0b22", "name": "Very large file: components/runtime/FlowstateRuntime.tsx (2504 lines)", "shortDescription": {"text": "Very large file: components/runtime/FlowstateRuntime.tsx (2504 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-d8a82ada80150530", "name": "Very large file: app/api/cron/notifications/route.ts (1264 lines)", "shortDescription": {"text": "Very large file: app/api/cron/notifications/route.ts (1264 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-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 58 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 156 placeholder/mock markers across 61 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-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. 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-cc1c69598b601a84", "name": "Agent authority lacks a verifier contract: .claude/commands/push.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/commands/push.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-7d6035b55691396b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 __tests__/pwa/offline-service-worker.test.ts:23", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 __tests__/pwa/offline-service-worker.test.ts:23"}, "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-cbb24f8f1d916c54", "name": "Commented-code block (5 lines) in types/index.ts:761", "shortDescription": {"text": "Commented-code block (5 lines) in types/index.ts:761"}, "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-66f85ec121c6e306", "name": "Commented-code block (9 lines) in mcp/reports/tests/tool-registration.test.ts:14", "shortDescription": {"text": "Commented-code block (9 lines) in mcp/reports/tests/tool-registration.test.ts:14"}, "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-53c8cd0ddfed5511", "name": "Commented-code block (13 lines) in mcp/reports/scripts/generate-arc-gif.mjs:5", "shortDescription": {"text": "Commented-code block (13 lines) in mcp/reports/scripts/generate-arc-gif.mjs:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-29099ec87a76678d", "name": "Commented-code block (5 lines) in mcp/reports/src/impactTiers.ts:3", "shortDescription": {"text": "Commented-code block (5 lines) in mcp/reports/src/impactTiers.ts:3"}, "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-5d1fa43d9950ae1d", "name": "Commented-code block (5 lines) in mcp/reports/src/report-window.ts:15", "shortDescription": {"text": "Commented-code block (5 lines) in mcp/reports/src/report-window.ts:15"}, "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-313e4dac20b3d216", "name": "Commented-code block (5 lines) in mcp/reports/src/supabase.ts:10", "shortDescription": {"text": "Commented-code block (5 lines) in mcp/reports/src/supabase.ts:10"}, "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-f52562e228de0689", "name": "Commented-code block (9 lines) in mcp/reports/src/templates/render.ts:22", "shortDescription": {"text": "Commented-code block (9 lines) in mcp/reports/src/templates/render.ts:22"}, "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-42ab4fb967845615", "name": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/contractAlerts.ts:5", "shortDescription": {"text": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/contractAlerts.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0828a6a4b81216cb", "name": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/activeWork.ts:5", "shortDescription": {"text": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/activeWork.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-cf949c3dce32ab46", "name": "Commented-code block (6 lines) in mcp/reports/src/templates/sections/boardMeetings.ts:5", "shortDescription": {"text": "Commented-code block (6 lines) in mcp/reports/src/templates/sections/boardMeetings.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-73f8e8ad4396337d", "name": "Commented-code block (6 lines) in mcp/reports/src/templates/sections/onHold.ts:5", "shortDescription": {"text": "Commented-code block (6 lines) in mcp/reports/src/templates/sections/onHold.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-27f21da66f886fb0", "name": "Commented-code block (8 lines) in mcp/reports/src/templates/sections/completed.ts:5", "shortDescription": {"text": "Commented-code block (8 lines) in mcp/reports/src/templates/sections/completed.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6ef3775ddbd765f2", "name": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/inspectionAlert.ts:5", "shortDescription": {"text": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/inspectionAlert.ts:5"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3cea8be426000e67", "name": "Commented-code block (6 lines) in scripts/check-bundle-budgets.mjs:8", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/check-bundle-budgets.mjs:8"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-56b1cd556487fcc2", "name": "Legacy-named symbol `handleClearLegacy` in components/SettingsModal.tsx:359", "shortDescription": {"text": "Legacy-named symbol `handleClearLegacy` in components/SettingsModal.tsx:359"}, "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-f561019104f6646d", "name": "Commented-code block (6 lines) in components/KanbanColumn.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in components/KanbanColumn.tsx:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e6074277fffa55f3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 components/toolkit/reports/ReportsPanel.tsx:51", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 components/toolkit/reports/ReportsPanel.tsx:51"}, "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-09944e108361d8bf", "name": "Commented-code block (9 lines) in components/runtime/FlowstateRuntime.tsx:176", "shortDescription": {"text": "Commented-code block (9 lines) in components/runtime/FlowstateRuntime.tsx:176"}, "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-0ae4b6fe0f6d8853", "name": "Commented-code block (5 lines) in contexts/TaskDetailContext.tsx:85", "shortDescription": {"text": "Commented-code block (5 lines) in contexts/TaskDetailContext.tsx:85"}, "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-99af3af175ae064b", "name": "Commented-code block (8 lines) in app/api/cron/notifications/route.ts:42", "shortDescription": {"text": "Commented-code block (8 lines) in app/api/cron/notifications/route.ts:42"}, "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-3d9d37bb0b746319", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/api-client.ts:3", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/api-client.ts:3"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ec2237103b6f4bb1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/notifications/push.ts:299", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/notifications/push.ts:299"}, "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-8b4549f369dad815", "name": "Commented-code block (5 lines) in lib/storage/migrations.ts:27", "shortDescription": {"text": "Commented-code block (5 lines) in lib/storage/migrations.ts:27"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ef4d51c2a7a71edf", "name": "Commented-code block (5 lines) in packages/types/src/domain.d.ts:438", "shortDescription": {"text": "Commented-code block (5 lines) in packages/types/src/domain.d.ts:438"}, "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-4169b7001825d86f", "name": "Commented-code block (6 lines) in hooks/useCloudStorage.ts:251", "shortDescription": {"text": "Commented-code block (6 lines) in hooks/useCloudStorage.ts:251"}, "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-f808a4ef3e1071fb", "name": "14 env vars used in code but missing from .env.example", "shortDescription": {"text": "14 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `ADMIN_EMAIL`, `ARC_GIF_PYTHON`, `CI`, `CRON_SECRET`, `E2E_START_SERVER`, `FLOWSTATE_ROOT`, `NEXT_RUNTIME`, `NODE_ENV` + 6 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}}]}}, "automationDetails": {"id": "repobility/19600"}, "properties": {"repository": "ShuromiU/flowstate", "repoUrl": "https://github.com/ShuromiU/flowstate", "branch": "main"}, "results": [{"ruleId": "scanner-bead75b0f9233e05", "level": "none", "message": {"text": "No API endpoints detected"}, "properties": {"repobilityId": "0f8bb852027c38f8", "scanner": "scanner-primary", "fingerprint": "bead75b0f9233e05", "layer": "api", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-2dadaca996bfd872", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-orphaned-recurrence.ts:28"}, "properties": {"repobilityId": "30be14a72519989b", "scanner": "scanner-primary", "fingerprint": "2dadaca996bfd872", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-602c2012c6fc79af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-recurrence.ts:9"}, "properties": {"repobilityId": "45c9dc05c69d3b6b", "scanner": "scanner-primary", "fingerprint": "602c2012c6fc79af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-01d46ad14f59361b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ActivityFeed.tsx:169"}, "properties": {"repobilityId": "80499fc6de0a65a6", "scanner": "scanner-primary", "fingerprint": "01d46ad14f59361b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f8381ce1b55587cc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/RecurringTasksPanel.tsx:150"}, "properties": {"repobilityId": "9f4d9c0cb020e73a", "scanner": "scanner-primary", "fingerprint": "f8381ce1b55587cc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-369bb488401bcd2c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/DependenciesSection.tsx:219"}, "properties": {"repobilityId": "ff7d388a58ea86e8", "scanner": "scanner-primary", "fingerprint": "369bb488401bcd2c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8b2390d58ef2aa94", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ArchiveManager.tsx:102"}, "properties": {"repobilityId": "a83dff792bebf46c", "scanner": "scanner-primary", "fingerprint": "8b2390d58ef2aa94", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6ebee2b6f1221ca7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/DuplicateToProjectsModal.tsx:74"}, "properties": {"repobilityId": "1bdcc95fc1312265", "scanner": "scanner-primary", "fingerprint": "6ebee2b6f1221ca7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f684b6d3d0cc87f8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/BulkActionsToolbar.tsx:213"}, "properties": {"repobilityId": "671896690e3de619", "scanner": "scanner-primary", "fingerprint": "f684b6d3d0cc87f8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3be898c5a1bef50f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/SettingsModal.tsx:433"}, "properties": {"repobilityId": "186f37eac4b408d2", "scanner": "scanner-primary", "fingerprint": "3be898c5a1bef50f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0116dc14339516d5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/TaskRelatedItems.tsx:78"}, "properties": {"repobilityId": "5f116146a02bd113", "scanner": "scanner-primary", "fingerprint": "0116dc14339516d5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3aa257cf23a09ce3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/NavigationRail.tsx:388"}, "properties": {"repobilityId": "3b91f32d6aec130c", "scanner": "scanner-primary", "fingerprint": "3aa257cf23a09ce3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7072c5f8e89a7099", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/KanbanBoard.tsx:951"}, "properties": {"repobilityId": "ccf6c390a870d85c", "scanner": "scanner-primary", "fingerprint": "7072c5f8e89a7099", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0ef3967dc295fe47", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AutomationRulesPanel.tsx:144"}, "properties": {"repobilityId": "cd9a6a342ad45f01", "scanner": "scanner-primary", "fingerprint": "0ef3967dc295fe47", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c0edddc03ff4f130", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/NotificationBell.tsx:280"}, "properties": {"repobilityId": "c0629acd9f83a6f8", "scanner": "scanner-primary", "fingerprint": "c0edddc03ff4f130", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-750bbc139e006bd0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AttachmentsSection.tsx:311"}, "properties": {"repobilityId": "7480fdca39c1e795", "scanner": "scanner-primary", "fingerprint": "750bbc139e006bd0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0c8208d9193029a1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/AddTaskModal.tsx:665"}, "properties": {"repobilityId": "858fc70fed1da96c", "scanner": "scanner-primary", "fingerprint": "0c8208d9193029a1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f91120d9bec2824f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/ProjectSelector.tsx:195"}, "properties": {"repobilityId": "3c32716af5bdbae3", "scanner": "scanner-primary", "fingerprint": "f91120d9bec2824f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-185f86133f9df0da", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/CompletedTasksReport.tsx:577"}, "properties": {"repobilityId": "c6baa047536dbd7c", "scanner": "scanner-primary", "fingerprint": "185f86133f9df0da", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0dcaf65b2baae2f3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/FilterBar.tsx:435"}, "properties": {"repobilityId": "7241b94d1f982491", "scanner": "scanner-primary", "fingerprint": "0dcaf65b2baae2f3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a1acfd8c7dd2ec01", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/settings/AccountSettingsView.tsx:411"}, "properties": {"repobilityId": "63419baa888f3fcf", "scanner": "scanner-primary", "fingerprint": "a1acfd8c7dd2ec01", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-aee2fea674437a6c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/settings/SettingsShell.tsx:108"}, "properties": {"repobilityId": "fd47697349a055e9", "scanner": "scanner-primary", "fingerprint": "aee2fea674437a6c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-47539213df9d3189", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/settings/ProjectSettingsView.tsx:131"}, "properties": {"repobilityId": "fbccf7846d801983", "scanner": "scanner-primary", "fingerprint": "47539213df9d3189", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d57e002476f0f0e2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/auth/AuthShell.tsx:154"}, "properties": {"repobilityId": "cabbc6e561a7ed20", "scanner": "scanner-primary", "fingerprint": "d57e002476f0f0e2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-aa3884a6b2a36918", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/task/LinkedTab.tsx:60"}, "properties": {"repobilityId": "e83914824a08016b", "scanner": "scanner-primary", "fingerprint": "aa3884a6b2a36918", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c0bae82d18b192a8", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 components/toolkit/reports/ReportsPreview.tsx:37"}, "properties": {"repobilityId": "b0b61d0102224017", "scanner": "scanner-primary", "fingerprint": "c0bae82d18b192a8", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-87a71ff22d69ddaf", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/toolkit/reports/ReportsPanel.tsx:334"}, "properties": {"repobilityId": "33f3722e7ca2d0bf", "scanner": "scanner-primary", "fingerprint": "87a71ff22d69ddaf", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4602075f07183c70", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobilePortfolio.tsx:164"}, "properties": {"repobilityId": "a8130af773db8e54", "scanner": "scanner-primary", "fingerprint": "4602075f07183c70", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0b78c25fb8b88cde", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileTaskDetail.tsx:162"}, "properties": {"repobilityId": "ca3e983bd057cfde", "scanner": "scanner-primary", "fingerprint": "0b78c25fb8b88cde", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-da797ecba1bdc68f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileProjectBoard.tsx:67"}, "properties": {"repobilityId": "9c9a1630511c4373", "scanner": "scanner-primary", "fingerprint": "da797ecba1bdc68f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8319ecb05df2da1f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileInbox.tsx:164"}, "properties": {"repobilityId": "9fae278b63d25ac0", "scanner": "scanner-primary", "fingerprint": "8319ecb05df2da1f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ae8110d5dff51213", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileToday.tsx:56"}, "properties": {"repobilityId": "40be9bf4474b385c", "scanner": "scanner-primary", "fingerprint": "ae8110d5dff51213", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-70f35099d7c222f7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/MobileProfile.tsx:58"}, "properties": {"repobilityId": "9ab23a941a6dc277", "scanner": "scanner-primary", "fingerprint": "70f35099d7c222f7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f204384d852e8b80", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/VendorManagementView.tsx:393"}, "properties": {"repobilityId": "a8c97588e1f70d54", "scanner": "scanner-primary", "fingerprint": "f204384d852e8b80", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b3cfc305c834a399", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/ArcReviewDrawer.tsx:186"}, "properties": {"repobilityId": "b7e356f7f21279f2", "scanner": "scanner-primary", "fingerprint": "b3cfc305c834a399", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2693727f52c81dd0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/BoardMeetingsView.tsx:562"}, "properties": {"repobilityId": "052579af66170d38", "scanner": "scanner-primary", "fingerprint": "2693727f52c81dd0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ddd422e34cb4f9fe", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/NoticeTemplateView.tsx:166"}, "properties": {"repobilityId": "4bbe57252815592a", "scanner": "scanner-primary", "fingerprint": "ddd422e34cb4f9fe", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-74302c86de6eb1b7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/InspectionDateWidget.tsx:371"}, "properties": {"repobilityId": "88f191d2944e9764", "scanner": "scanner-primary", "fingerprint": "74302c86de6eb1b7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6773717dfce89089", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/LienManagementView.tsx:443"}, "properties": {"repobilityId": "48213140d3935495", "scanner": "scanner-primary", "fingerprint": "6773717dfce89089", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b33b85225ed26525", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/BoardMemberRegistry.tsx:186"}, "properties": {"repobilityId": "298e00c0c8054634", "scanner": "scanner-primary", "fingerprint": "b33b85225ed26525", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-19f20a710a56f65a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/hoa/ArcFilesPanel.tsx:131"}, "properties": {"repobilityId": "bad5dab45db84943", "scanner": "scanner-primary", "fingerprint": "19f20a710a56f65a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f1179b9c2126c452", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/runtime/FlowstateRuntime.tsx:2107"}, "properties": {"repobilityId": "0c9a380c7ad6cfc3", "scanner": "scanner-primary", "fingerprint": "f1179b9c2126c452", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-58e3f1677204e376", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/notes/NoteBubble.tsx:143"}, "properties": {"repobilityId": "30180676fc518a1b", "scanner": "scanner-primary", "fingerprint": "58e3f1677204e376", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-077c6ea97205cd52", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/pulse/BoardDayRitual.tsx:86"}, "properties": {"repobilityId": "3a360646bc5725a5", "scanner": "scanner-primary", "fingerprint": "077c6ea97205cd52", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f804495970e6882f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/pulse/PortfolioBiPanel.tsx:106"}, "properties": {"repobilityId": "4c63c747f8765e7e", "scanner": "scanner-primary", "fingerprint": "f804495970e6882f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4f0817fce86d68ab", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/RecordPeekDrawer.tsx:148"}, "properties": {"repobilityId": "cece9645f6a7f1c4", "scanner": "scanner-primary", "fingerprint": "4f0817fce86d68ab", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca7dc7f8a9567ffb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/MeetingPeekPanel.tsx:70"}, "properties": {"repobilityId": "6c72d4f256bc416d", "scanner": "scanner-primary", "fingerprint": "ca7dc7f8a9567ffb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-79d268b9dd4e64cb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/InspectionPeekPanel.tsx:37"}, "properties": {"repobilityId": "bb0d8c6c1967737d", "scanner": "scanner-primary", "fingerprint": "79d268b9dd4e64cb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-98f88ce27abd998c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/record/panels/RecordPanelPrimitives.tsx:24"}, "properties": {"repobilityId": "0c666d3b109ffbed", "scanner": "scanner-primary", "fingerprint": "98f88ce27abd998c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ae735b05242aae93", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/inbox/InboxView.tsx:384"}, "properties": {"repobilityId": "7b48f1f0b92eac80", "scanner": "scanner-primary", "fingerprint": "ae735b05242aae93", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6f71ee8358be4444", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/views/DashboardView.tsx:236"}, "properties": {"repobilityId": "55275d124cccd4b0", "scanner": "scanner-primary", "fingerprint": "6f71ee8358be4444", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f55aea805746237d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/views/TimelineView.tsx:378"}, "properties": {"repobilityId": "fa9ca44da931b2bc", "scanner": "scanner-primary", "fingerprint": "f55aea805746237d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b024b5ad5dfceb68", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/views/MyDayView.tsx:394"}, "properties": {"repobilityId": "b7f153941a3b32ea", "scanner": "scanner-primary", "fingerprint": "b024b5ad5dfceb68", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e57ab0fecf76346d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/MoreItemsPopover.tsx:75"}, "properties": {"repobilityId": "85d405e0670a50b1", "scanner": "scanner-primary", "fingerprint": "e57ab0fecf76346d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b10cc0071eec2366", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarMiniSidebar.tsx:141"}, "properties": {"repobilityId": "cc2ae457905af1f7", "scanner": "scanner-primary", "fingerprint": "b10cc0071eec2366", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c836c984e680a62f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarQuarterView.tsx:252"}, "properties": {"repobilityId": "d370415ebde31b0f", "scanner": "scanner-primary", "fingerprint": "c836c984e680a62f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c55dc656c42c63b8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarFilters.tsx:187"}, "properties": {"repobilityId": "6df5b23df319aa23", "scanner": "scanner-primary", "fingerprint": "c55dc656c42c63b8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b08db60c6c52f617", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/calendar/CalendarMeetingPopover.tsx:75"}, "properties": {"repobilityId": "a5819a23e37089e7", "scanner": "scanner-primary", "fingerprint": "b08db60c6c52f617", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-805859c20f4941db", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/board/BoardSignalShelf.tsx:199"}, "properties": {"repobilityId": "5d4233684c96df0e", "scanner": "scanner-primary", "fingerprint": "805859c20f4941db", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-85a5cd5820c16ba0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/admin/page.tsx:465"}, "properties": {"repobilityId": "9c2c16c32be292da", "scanner": "scanner-primary", "fingerprint": "85a5cd5820c16ba0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e8687cf5807c5dfb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/(app)/settings/notifications/page.tsx:470"}, "properties": {"repobilityId": "0f02b8c0a92135ff", "scanner": "scanner-primary", "fingerprint": "e8687cf5807c5dfb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-46e13c94ffe3d79e", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 lib/dev-logger.ts:15"}, "properties": {"repobilityId": "c059143819f4426e", "scanner": "scanner-primary", "fingerprint": "46e13c94ffe3d79e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-af86d6b3695cb6af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 lib/server-logger.ts:49"}, "properties": {"repobilityId": "0246d7b61111d368", "scanner": "scanner-primary", "fingerprint": "af86d6b3695cb6af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-124d78d5053b240b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 lib/logger.ts:62"}, "properties": {"repobilityId": "828e96ab86ae12d1", "scanner": "scanner-primary", "fingerprint": "124d78d5053b240b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b46853cb3c6d2574", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 hooks/useInstallPrompt.ts:101"}, "properties": {"repobilityId": "9389ad5e958e84d7", "scanner": "scanner-primary", "fingerprint": "b46853cb3c6d2574", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b7c9b0b79da78bbe", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in __tests__/hooks/use-keyboard-shortcuts.test.tsx:21"}, "properties": {"repobilityId": "b9187bf9fcdc5674", "scanner": "scanner-primary", "fingerprint": "b7c9b0b79da78bbe", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "__tests__/hooks/use-keyboard-shortcuts.test.tsx"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-a0c4ed60b6154411", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in mcp/reports/scripts/generate-arc-gif.mjs:30"}, "properties": {"repobilityId": "fdc8a6fd360989e1", "scanner": "scanner-primary", "fingerprint": "a0c4ed60b6154411", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mcp/reports/scripts/generate-arc-gif.mjs"}, "region": {"startLine": 30}}}]}, {"ruleId": "scanner-826f62f977030901", "level": "error", "message": {"text": "Insecure pattern 'eval_used' in scripts/check-bundle-budgets.mjs:103"}, "properties": {"repobilityId": "e703efa34aa88163", "scanner": "scanner-primary", "fingerprint": "826f62f977030901", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["owasp", "eval_used"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/check-bundle-budgets.mjs"}, "region": {"startLine": 103}}}]}, {"ruleId": "scanner-49e8b71c15671695", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in components/RichTextEditor.tsx:146"}, "properties": {"repobilityId": "402c94ab1afbbdf6", "scanner": "scanner-primary", "fingerprint": "49e8b71c15671695", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "components/RichTextEditor.tsx"}, "region": {"startLine": 146}}}]}, {"ruleId": "scanner-4a8fdc1fe7ed126d", "level": "warning", "message": {"text": "Insecure pattern 'domparser_html_parse' in components/RichTextEditor.tsx:27"}, "properties": {"repobilityId": "87f3f732fa05809a", "scanner": "scanner-primary", "fingerprint": "4a8fdc1fe7ed126d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "domparser_html_parse"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "components/RichTextEditor.tsx"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-c90d6e7be33e2093", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in components/toolkit/reports/ReportsPreview.tsx:37"}, "properties": {"repobilityId": "1bfc4d8656c219a8", "scanner": "scanner-primary", "fingerprint": "c90d6e7be33e2093", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "components/toolkit/reports/ReportsPreview.tsx"}, "region": {"startLine": 37}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "ae16880318b99912", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-d3f51f44744f42ec", "level": "note", "message": {"text": "Very large file: types/supabase.generated.ts (2089 lines)"}, "properties": {"repobilityId": "16a4af23a64a46d8", "scanner": "scanner-primary", "fingerprint": "d3f51f44744f42ec", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-159ba78fd7540205", "level": "note", "message": {"text": "Very large file: components/HelpGuide.tsx (1413 lines)"}, "properties": {"repobilityId": "fef4b870e3fa442f", "scanner": "scanner-primary", "fingerprint": "159ba78fd7540205", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-7ad89b77409d6ea6", "level": "note", "message": {"text": "Very large file: components/AddTaskModal.tsx (1606 lines)"}, "properties": {"repobilityId": "1aaf2c52d34dd867", "scanner": "scanner-primary", "fingerprint": "7ad89b77409d6ea6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-a2ceea2c409b0b22", "level": "note", "message": {"text": "Very large file: components/runtime/FlowstateRuntime.tsx (2504 lines)"}, "properties": {"repobilityId": "0b1ae1ee87123761", "scanner": "scanner-primary", "fingerprint": "a2ceea2c409b0b22", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-d8a82ada80150530", "level": "note", "message": {"text": "Very large file: app/api/cron/notifications/route.ts (1264 lines)"}, "properties": {"repobilityId": "b9b81e5e0ac2cdba", "scanner": "scanner-primary", "fingerprint": "d8a82ada80150530", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "9f6872a3f32750c4", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "1144d77cc6122572", "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": "b9339c1f93737646", "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": "662ed987a4f85f6d", "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": "7e120f8b543933e8", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "7aac9c75654e4e25", "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": "2871cba60648f49c", "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": "57f4c2951b150af0", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-cc1c69598b601a84", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/commands/push.md"}, "properties": {"repobilityId": "35c259eb411f7d7f", "scanner": "scanner-primary", "fingerprint": "cc1c69598b601a84", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/commands/push.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7d6035b55691396b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 __tests__/pwa/offline-service-worker.test.ts:23"}, "properties": {"repobilityId": "4ac85a17c03f0526", "scanner": "scanner-primary", "fingerprint": "7d6035b55691396b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cbb24f8f1d916c54", "level": "none", "message": {"text": "Commented-code block (5 lines) in types/index.ts:761"}, "properties": {"repobilityId": "f3be797806aeda2d", "scanner": "scanner-primary", "fingerprint": "cbb24f8f1d916c54", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-66f85ec121c6e306", "level": "none", "message": {"text": "Commented-code block (9 lines) in mcp/reports/tests/tool-registration.test.ts:14"}, "properties": {"repobilityId": "4b27cf4d6d990c44", "scanner": "scanner-primary", "fingerprint": "66f85ec121c6e306", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-53c8cd0ddfed5511", "level": "none", "message": {"text": "Commented-code block (13 lines) in mcp/reports/scripts/generate-arc-gif.mjs:5"}, "properties": {"repobilityId": "0aa52d34053f9993", "scanner": "scanner-primary", "fingerprint": "53c8cd0ddfed5511", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-29099ec87a76678d", "level": "none", "message": {"text": "Commented-code block (5 lines) in mcp/reports/src/impactTiers.ts:3"}, "properties": {"repobilityId": "f6d23dc4c1089949", "scanner": "scanner-primary", "fingerprint": "29099ec87a76678d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5d1fa43d9950ae1d", "level": "none", "message": {"text": "Commented-code block (5 lines) in mcp/reports/src/report-window.ts:15"}, "properties": {"repobilityId": "21ee1ee4fb29e8f9", "scanner": "scanner-primary", "fingerprint": "5d1fa43d9950ae1d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-313e4dac20b3d216", "level": "none", "message": {"text": "Commented-code block (5 lines) in mcp/reports/src/supabase.ts:10"}, "properties": {"repobilityId": "c1edcf030e1ca23c", "scanner": "scanner-primary", "fingerprint": "313e4dac20b3d216", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f52562e228de0689", "level": "none", "message": {"text": "Commented-code block (9 lines) in mcp/reports/src/templates/render.ts:22"}, "properties": {"repobilityId": "c0e753bd3837923e", "scanner": "scanner-primary", "fingerprint": "f52562e228de0689", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-42ab4fb967845615", "level": "none", "message": {"text": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/contractAlerts.ts:5"}, "properties": {"repobilityId": "ecc371ad5f9a83bd", "scanner": "scanner-primary", "fingerprint": "42ab4fb967845615", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0828a6a4b81216cb", "level": "none", "message": {"text": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/activeWork.ts:5"}, "properties": {"repobilityId": "57b0e14cab5b4fcb", "scanner": "scanner-primary", "fingerprint": "0828a6a4b81216cb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cf949c3dce32ab46", "level": "none", "message": {"text": "Commented-code block (6 lines) in mcp/reports/src/templates/sections/boardMeetings.ts:5"}, "properties": {"repobilityId": "c069c780d1398703", "scanner": "scanner-primary", "fingerprint": "cf949c3dce32ab46", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-73f8e8ad4396337d", "level": "none", "message": {"text": "Commented-code block (6 lines) in mcp/reports/src/templates/sections/onHold.ts:5"}, "properties": {"repobilityId": "1079355df48e1ac3", "scanner": "scanner-primary", "fingerprint": "73f8e8ad4396337d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-27f21da66f886fb0", "level": "none", "message": {"text": "Commented-code block (8 lines) in mcp/reports/src/templates/sections/completed.ts:5"}, "properties": {"repobilityId": "3a94c7a0b67fa3e3", "scanner": "scanner-primary", "fingerprint": "27f21da66f886fb0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6ef3775ddbd765f2", "level": "none", "message": {"text": "Commented-code block (7 lines) in mcp/reports/src/templates/sections/inspectionAlert.ts:5"}, "properties": {"repobilityId": "3d366c25ffb09307", "scanner": "scanner-primary", "fingerprint": "6ef3775ddbd765f2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3cea8be426000e67", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/check-bundle-budgets.mjs:8"}, "properties": {"repobilityId": "90840dc70a90fc84", "scanner": "scanner-primary", "fingerprint": "3cea8be426000e67", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-56b1cd556487fcc2", "level": "note", "message": {"text": "Legacy-named symbol `handleClearLegacy` in components/SettingsModal.tsx:359"}, "properties": {"repobilityId": "fac9fa0e85bd9d0e", "scanner": "scanner-primary", "fingerprint": "56b1cd556487fcc2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-f561019104f6646d", "level": "none", "message": {"text": "Commented-code block (6 lines) in components/KanbanColumn.tsx:1"}, "properties": {"repobilityId": "bd5764a8cc0db480", "scanner": "scanner-primary", "fingerprint": "f561019104f6646d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e6074277fffa55f3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 components/toolkit/reports/ReportsPanel.tsx:51"}, "properties": {"repobilityId": "0f4e445556b0cafb", "scanner": "scanner-primary", "fingerprint": "e6074277fffa55f3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-09944e108361d8bf", "level": "none", "message": {"text": "Commented-code block (9 lines) in components/runtime/FlowstateRuntime.tsx:176"}, "properties": {"repobilityId": "6577bbde78e5da7f", "scanner": "scanner-primary", "fingerprint": "09944e108361d8bf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ae4b6fe0f6d8853", "level": "none", "message": {"text": "Commented-code block (5 lines) in contexts/TaskDetailContext.tsx:85"}, "properties": {"repobilityId": "17582974a588c325", "scanner": "scanner-primary", "fingerprint": "0ae4b6fe0f6d8853", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-99af3af175ae064b", "level": "none", "message": {"text": "Commented-code block (8 lines) in app/api/cron/notifications/route.ts:42"}, "properties": {"repobilityId": "9179987855ac87b1", "scanner": "scanner-primary", "fingerprint": "99af3af175ae064b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3d9d37bb0b746319", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/api-client.ts:3"}, "properties": {"repobilityId": "60213bef6ad836cc", "scanner": "scanner-primary", "fingerprint": "3d9d37bb0b746319", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ec2237103b6f4bb1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/notifications/push.ts:299"}, "properties": {"repobilityId": "8102cc015a1454cb", "scanner": "scanner-primary", "fingerprint": "ec2237103b6f4bb1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8b4549f369dad815", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/storage/migrations.ts:27"}, "properties": {"repobilityId": "bdc37324680a25c7", "scanner": "scanner-primary", "fingerprint": "8b4549f369dad815", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ef4d51c2a7a71edf", "level": "none", "message": {"text": "Commented-code block (5 lines) in packages/types/src/domain.d.ts:438"}, "properties": {"repobilityId": "4a7aa7baba37ab70", "scanner": "scanner-primary", "fingerprint": "ef4d51c2a7a71edf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4169b7001825d86f", "level": "none", "message": {"text": "Commented-code block (6 lines) in hooks/useCloudStorage.ts:251"}, "properties": {"repobilityId": "9e25e522fc3614da", "scanner": "scanner-primary", "fingerprint": "4169b7001825d86f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f808a4ef3e1071fb", "level": "note", "message": {"text": "14 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "ce6b2ec4be4ec75a", "scanner": "scanner-primary", "fingerprint": "f808a4ef3e1071fb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}