{"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-15974498ea95a716", "name": "Stray `console.log` in TS/JS \u2014 compose/mock-idp/src/index.ts:90", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 compose/mock-idp/src/index.ts:90"}, "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-7a6fe9a25cca0fe6", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginUsername.tsx:26", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginUsername.tsx:26"}, "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-c9c8e611fa2b5f26", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx:31", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx:31"}, "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-1177e75f39127594", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginPassword.tsx:26", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginPassword.tsx:26"}, "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-90ac53883eb5887a", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Error.tsx:39", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Error.tsx:39"}, "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-593b0a4808fe41c6", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Login.tsx:26", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Login.tsx:26"}, "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-26701620bb8655e2", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Register.tsx:29", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Register.tsx:29"}, "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-9b90c70affe928f0", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Info.tsx:29", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Info.tsx:29"}, "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-235fbef46eb9baca", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/sidebar-user-footer.tsx:58", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/sidebar-user-footer.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-58ee246c6a98803a", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/mobile-sidebar.tsx:74", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/mobile-sidebar.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-66c972fe4359beff", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/desktop-sidebar.tsx:75", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/desktop-sidebar.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-2273e39437db80ff", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth-header-controls.tsx:24", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth-header-controls.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-eaf363f32cf73698", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/settings/org-documents-section.tsx:111", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/settings/org-documents-section.tsx:111"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-23f1d0ce2f46a935", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/disbursement-list-view.tsx:200", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/disbursement-list-view.tsx:200"}, "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-0899cb2c96952a41", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/upcoming-court-dates-widget.tsx:126", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/upcoming-court-dates-widget.tsx:126"}, "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-23a1c4aaaf4c488c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/tariff-line-dialog.tsx:208", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/tariff-line-dialog.tsx:208"}, "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-c172189ca2584c9d", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/ai/compliance-finding-list.tsx:194", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/ai/compliance-finding-list.tsx:194"}, "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-8c9be3ca4806edb7", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/ai/contract-review-results.tsx:69", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/ai/contract-review-results.tsx:69"}, "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-522dbc07ff67fff4", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/mock-org-switcher.tsx:12", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/mock-org-switcher.tsx:12"}, "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-b6fedb5005ac6285", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/mock-user-button.tsx:45", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/mock-user-button.tsx:45"}, "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-9b52f61a8d1f037d", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/user-menu-bff.tsx:143", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/user-menu-bff.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-fa7c62f7970a0c75", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/project-members-panel.tsx:178", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/project-members-panel.tsx:178"}, "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-c7ac80aad3eb543e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/add-member-dialog.tsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/add-member-dialog.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-f51e5f1bc5e179c5", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/link-customer-dialog.tsx:126", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/link-customer-dialog.tsx:126"}, "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-e29bde87b127cfa1", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/upcoming-deadlines-tile.tsx:38", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/upcoming-deadlines-tile.tsx:38"}, "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-8995c8c287c566a4", "name": "TODO/FIXME marker in shipping code \u2014 frontend/components/activity/activity-feed-client.tsx:40", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/activity/activity-feed-client.tsx:40"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-374dc6a64b81d8b2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/recent-activity-widget.tsx:108", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/recent-activity-widget.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-0e943d5563ea49d4", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/incomplete-profiles-widget.tsx:84", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/incomplete-profiles-widget.tsx:84"}, "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-df63eb3f68ac4bbe", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/my-schedule-widget.tsx:73", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/my-schedule-widget.tsx:73"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c65230e8a0272bd9", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/sensitive-events-widget.tsx:140", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/sensitive-events-widget.tsx:140"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0fde7cee00798054", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/project-health-widget.tsx:192", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/project-health-widget.tsx:192"}, "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-0d74f2d3c9b8c11e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/my-week-column.tsx:47", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/my-week-column.tsx:47"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-88ef603843b704b2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/todays-agenda.tsx:60", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/todays-agenda.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-6ccf9193573135ff", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/proposals/create-proposal-dialog.tsx:295", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/proposals/create-proposal-dialog.tsx:295"}, "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-8c0de58332381466", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/rates/member-rates-table.tsx:186", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/rates/member-rates-table.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-3c0b00a158f8c793", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/capacity/allocation-popover.tsx:178", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/capacity/allocation-popover.tsx:178"}, "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-e32246051b2bfca3", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/time-tracking/weekly-time-grid.tsx:493", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/time-tracking/weekly-time-grid.tsx:493"}, "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-9e1027d7b0d34d85", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/customers/link-project-dialog.tsx:123", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/customers/link-project-dialog.tsx:123"}, "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-37d7794bf2e32424", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/audit/audit-timeline.tsx:161", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/audit/audit-timeline.tsx:161"}, "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-fa1bf2af9b8a29fa", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/TemplatePreviewDialog.tsx:203", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/TemplatePreviewDialog.tsx:203"}, "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-f974787e0812d937", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/clause-picker-dialog.tsx:217", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/clause-picker-dialog.tsx:217"}, "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-5f9d309c171daab9", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/TemplatePicker.tsx:42", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/TemplatePicker.tsx:42"}, "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-7d2598797edce5c8", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/generation-clause-step.tsx:281", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/generation-clause-step.tsx:281"}, "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-4d6fb34e253b0beb", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/components/templates/generation-clause-step.tsx:309", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/components/templates/generation-clause-step.tsx:309"}, "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-a038dbc571e03144", "name": "TODO/FIXME marker in shipping code \u2014 frontend/components/templates/TemplateEditorClient.tsx:4", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/templates/TemplateEditorClient.tsx:4"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-026760ef21e73f97", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/assignee-selector.tsx:93", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/assignee-selector.tsx:93"}, "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-05f1e7a8c01799b2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/task-list-table-row.tsx:114", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/task-list-table-row.tsx:114"}, "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-6bf4b1a1c56d1825", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/time-entry-list.tsx:196", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/time-entry-list.tsx:196"}, "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-628fcb96dec4db49", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/compliance/CreateDataRequestDialog.tsx:189", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/compliance/CreateDataRequestDialog.tsx:189"}, "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-ed2d878a26bc087c", "name": "TODO/FIXME marker in shipping code \u2014 frontend/components/billing-runs/billing-run-wizard.tsx:31", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/billing-runs/billing-run-wizard.tsx:31"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2723eca69d4f1721", "name": "TODO/FIXME marker in shipping code \u2014 frontend/components/billing-runs/configure-step.tsx:43", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/billing-runs/configure-step.tsx:43"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b970aacfb380d3a2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/expenses/expense-list.tsx:281", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/expenses/expense-list.tsx:281"}, "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-1f19ca2024c1a7c2", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/expenses/log-expense-dialog.tsx:363", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/expenses/log-expense-dialog.tsx:363"}, "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-d9c7b0778555fcb9", "name": "TODO/FIXME marker in shipping code \u2014 frontend/components/assistant/specialist-panel.tsx:148", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/assistant/specialist-panel.tsx:148"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e5211ee6e1e711bf", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/trust/TrustEntityPickers.tsx:104", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/trust/TrustEntityPickers.tsx:104"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c69dbebc53eb7327", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/trust/ReconciliationSplitPane.tsx:192", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/trust/ReconciliationSplitPane.tsx:192"}, "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-3156d7ab09321026", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/portal/portal-document-table.tsx:98", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/portal/portal-document-table.tsx:98"}, "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-f248bfba2401d234", "name": "TODO/FIXME marker in shipping code \u2014 frontend/components/editor/EditorToolbar.tsx:174", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/editor/EditorToolbar.tsx:174"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a440acbe916d0b34", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/EntityPicker.tsx:171", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/EntityPicker.tsx:171"}, "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-6ae8283c0ab437bd", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/ClausePicker.tsx:168", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/ClausePicker.tsx:168"}, "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-dc8ae43cb6a68c48", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/node-views/ClauseBlockNodeView.tsx:41", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/node-views/ClauseBlockNodeView.tsx:41"}, "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-5958a0615ffee02b", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/node-views/ConditionalBlockNodeView.tsx:", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/node-views/ConditionalBlockNodeView.tsx:35"}, "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-7933082d580b17aa", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/urgency-task-list.tsx:169", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/urgency-task-list.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-b1d6197d097a22c4", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/weekly-time-summary.tsx:155", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/weekly-time-summary.tsx:155"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-44fe340ca3a58beb", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/today-time-entries.tsx:47", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/today-time-entries.tsx:47"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f785b64a4b55007d", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/available-task-list.tsx:114", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/available-task-list.tsx:114"}, "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-93830dab94ed671e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/my-expenses.tsx:51", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/my-expenses.tsx:51"}, "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-35892a6cc0ae15a1", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/assigned-task-list.tsx:123", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/assigned-task-list.tsx:123"}, "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-5addf6020cb8eb93", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/upload-progress-item.tsx:60", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/upload-progress-item.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-e9faa1db8135216c", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/customer-documents-panel.tsx:130", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/customer-documents-panel.tsx:130"}, "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-d378c79f112f107e", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/documents-panel.tsx:465", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/documents-panel.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-e4b111fd7a3712d6", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/clauses/clauses-content.tsx:376", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/clauses/clauses-content.tsx:376"}, "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-a717fa859745c42b", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/data-protection/processing-register-table.tsx:3", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/data-protection/processing-register-table.tsx:374"}, "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-bc14baa48b979333", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/retainers/create-retainer-dialog.tsx:195", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/retainers/create-retainer-dialog.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-9453e38b3a0a0d6d", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/portal/(authenticated)/proposals/[id]/page.tsx:315", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/portal/(authenticated)/proposals/[id]/page.tsx:315"}, "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-12beddd71267ed6f", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/platform-admin/demo/actions.ts:61", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/platform-admin/demo/actions.ts:61"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0e7f9f020f6afd90", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/layout.tsx:90", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/layout.tsx:90"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-47c650eaf3f65324", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/settings/integrations/xero/sync-log/actions.ts:72", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/settings/integrations/xero/sync-log/actions.ts:72"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f894f8aee3847e39", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/settings/audit-log/audit-log-client.tsx:299", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/settings/audit-log/audit-log-client.tsx:299"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-02971978a90ff3ac", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/settings/templates/FieldDiscoveryResu", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/settings/templates/FieldDiscoveryResults.tsx:26"}, "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-a6e31e17dc971576", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/legal/disbursements/[id]/detail-client.tsx:215", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/legal/disbursements/[id]/detail-client.tsx:215"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-51edbd87edd04a5a", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/projects/[id]/page.tsx:107", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/projects/[id]/page.tsx:107"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-13f79f501dd1f04a", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/projects/[id]/statement-actions.ts:55", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/projects/[id]/statement-actions.ts:55"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-be7105c9b3e49959", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/trust-accounting/actions.ts:84", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/trust-accounting/actions.ts:84"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6977498df71ad273", "name": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/trust-accounting/reconciliation/new/page.tsx:159", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/trust-accounting/reconciliation/new/page.tsx:159"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7461e4051b8caee0", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/calendar/calendar-list-view.tsx:110", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/calendar/calendar-list-view.tsx:110"}, "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-13195bfe611fd535", "name": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/calendar/calendar-month-view.tsx:221", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/calendar/calendar-month-view.tsx:221"}, "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-3c524cd6f5d0402a", "name": "TODO/FIXME marker in shipping code \u2014 frontend/lib/compliance-api.ts:101", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/lib/compliance-api.ts:101"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8f4fca88e43d8b3b", "name": "TODO/FIXME marker in shipping code \u2014 frontend/lib/messages/index.ts:32", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/lib/messages/index.ts:32"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b9a455a715181b8b", "name": "Stray `console.log` in TS/JS \u2014 frontend/e2e/tests/debug-kc-invite.spec.ts:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 frontend/e2e/tests/debug-kc-invite.spec.ts:17"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b24588d50d42660c", "name": "TODO/FIXME marker in shipping code \u2014 frontend/e2e/tests/admin-audit-30day/fixtures.ts:121", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/e2e/tests/admin-audit-30day/fixtures.ts:121"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c90d7c628ee40a88", "name": "TODO/FIXME marker in shipping code \u2014 frontend/e2e/tests/specialists/billing-launcher.spec.ts:30", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/e2e/tests/specialists/billing-launcher.spec.ts:30"}, "fullDescription": {"text": "Track in /reviews or /issues, not as a code comment that rots.\n\nWhy: Drift control \u2014 shouldn't be the same as Quality TODO scanner.\nRule id: fq.todo-marker"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ae10ecab1872c96e", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/components/portal-sidebar.tsx:69", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/portal-sidebar.tsx:69"}, "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-9c911c930f24e524", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/components/portal-topbar.tsx:60", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/portal-topbar.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-aedb51b6b451cc8d", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/components/document-list.tsx:57", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/document-list.tsx:57"}, "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-76e74767e48a8196", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/components/pending-acceptances-list.tsx:111", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/pending-acceptances-list.tsx:111"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a58b2879a17723b0", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/components/deadlines/deadline-list.tsx:287", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/deadlines/deadline-list.tsx:287"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8a67d7ca6b1203a4", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/app/(authenticated)/proposals/page.tsx:136", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/app/(authenticated)/proposals/page.tsx:136"}, "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-fb6436ddfdef8feb", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 portal/app/(authenticated)/proposals/[id]/page.tsx:278", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 portal/app/(authenticated)/proposals/[id]/page.tsx:278"}, "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-3cc26715a25121c1", "name": "`truncate` class without `title=` for hover reveal \u2014 portal/app/(authenticated)/trust/[matterId]/page.tsx:238", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/app/(authenticated)/trust/[matterId]/page.tsx:238"}, "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-fca7b196884fed0c", "name": "Privileged port 28 in use", "shortDescription": {"text": "Privileged port 28 in use"}, "fullDescription": {"text": "Port 28 is privileged (<1024). Make sure the service runs with the right caps or front it with a non-privileged port via a load balancer."}, "properties": {"scanner": "scanner-primary", "layer": "network", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-397746cf43b3c83f", "name": "Dockerfile runs as root: compose/mock-idp/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: compose/mock-idp/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3104e147acce2251", "name": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-03ae6e174e16a97e", "name": "Dockerfile runs as root: compose/seed/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: compose/seed/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fe4b01d6b0bc2703", "name": "Docker base image is tag-pinned but not digest-pinned: alpine:3.19", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: alpine:3.19"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-faa134129e5545ff", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-20bd6afcf637e243", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4f0add5abd530738", "name": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jdk", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jdk"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1a4540a7258d1030", "name": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jre-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jre-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e011d9f144b0dc64", "name": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jdk", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jdk"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-11f8caef0be4bb43", "name": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jre-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jre-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-aa5acaa49eb8315b", "name": "Containers defined but no K8s/orchestration manifest found", "shortDescription": {"text": "Containers defined but no K8s/orchestration manifest found"}, "fullDescription": {"text": "Repo has Dockerfiles/compose but no Kubernetes/Nomad manifests. If the target deployment is K8s, the manifests may live in a separate ops repo."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fc28be289986701a", "name": "Runtime dotenv file present in repo: compose/.env.keycloak", "shortDescription": {"text": "Runtime dotenv file present in repo: compose/.env.keycloak"}, "fullDescription": {"text": "`compose/.env.keycloak` looks like a runtime dotenv file. It contains secret-looking assignments for KEYCLOAK_CLIENT_SECRET, NEXTAUTH_SECRET, POSTGRES_PASSWORD, INTERNAL_API_KEY, PORTAL_JWT_SECRET. Move real values to a secret manager and keep only `.env.example` style templates in source control."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-5f3bd1a7930440da", "name": "Runtime dotenv file present in repo: frontend/.env.keycloak", "shortDescription": {"text": "Runtime dotenv file present in repo: frontend/.env.keycloak"}, "fullDescription": {"text": "`frontend/.env.keycloak` looks like a runtime dotenv file. It contains secret-looking assignments for NEXT_PUBLIC_KEYCLOAK_REALM, NEXT_PUBLIC_KEYCLOAK_CLIENT_ID, INTERNAL_API_KEY. Move real values to a secret manager and keep only `.env.example` style templates in source control."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-c5f94cff05775af9", "name": "Possible secret in compose/scripts/keycloak-bootstrap.sh", "shortDescription": {"text": "Possible secret in compose/scripts/keycloak-bootstrap.sh"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-e6645361781748b5", "name": "Insecure pattern 'cors_wildcard' in compose/mock-idp/src/index.ts:11", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in compose/mock-idp/src/index.ts:11"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4bed4205e408a488", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginUsername.tsx:26", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginUsername.tsx:26"}, "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-732108c9d3980c0a", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx:31", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx:31"}, "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-93c155e6b02942f7", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginPassword.tsx:26", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginPassword.tsx:26"}, "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-d51c8f6d2e61e291", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Error.tsx:39", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Error.tsx:39"}, "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-238a95d19252d36e", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Login.tsx:26", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Login.tsx:26"}, "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-10c7903b84a7d762", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Register.tsx:29", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Register.tsx:29"}, "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-e16d2bc412d091ed", "name": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Info.tsx:29", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Info.tsx:29"}, "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-ab36cd9ec774de0f", "name": "Insecure pattern 'node_child_process' in frontend/__tests__/ai/execution-gate-card.test.tsx:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in frontend/__tests__/ai/execution-gate-card.test.tsx:1"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9259fec4a6d913d7", "name": "Insecure pattern 'local_storage_auth_token' in frontend/components/auth/mock-login-form.tsx:48", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/components/auth/mock-login-form.tsx:48"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0d71d438cd6ade35", "name": "Insecure pattern 'dangerous_innerhtml' in frontend/app/portal/(authenticated)/proposals/[id]/page.tsx:315", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/portal/(authenticated)/proposals/[id]/page.tsx:315"}, "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-aa7a4c09127857ee", "name": "Insecure pattern 'local_storage_auth_token' in frontend/lib/auth/client/hooks.ts:88", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/lib/auth/client/hooks.ts:88"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-190e3a0306aa3f5c", "name": "Insecure pattern 'dangerous_innerhtml' in portal/app/(authenticated)/proposals/[id]/page.tsx:278", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in portal/app/(authenticated)/proposals/[id]/page.tsx:278"}, "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-f8920479ce13ff70", "name": "Insecure pattern 'local_storage_auth_token' in portal/e2e/helpers/auth.ts:79", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in portal/e2e/helpers/auth.ts:79"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-36514a6b17e1d602", "name": "Insecure pattern 'node_child_process' in tools/claude-slack-bot/src/claudeRunner.ts:1", "shortDescription": {"text": "Insecure pattern 'node_child_process' in tools/claude-slack-bot/src/claudeRunner.ts:1"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-35565ec7d80e5e78", "name": "Possible secret in backend/src/test/java/io/b2mash/b2b/b2bstrawman/integration/IntegrationControllerTest.java", "shortDescription": {"text": "Possible secret in backend/src/test/java/io/b2mash/b2b/b2bstrawman/integration/IntegrationControllerTest.java"}, "fullDescription": {"text": "Detected pattern matching generic_api_key. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-6634c4990e71e5d6", "name": "Insecure pattern 'weak_hash' in backend/src/main/java/io/b2mash/b2b/b2bstrawman/billing/SubscriptionItnService.java:306", "shortDescription": {"text": "Insecure pattern 'weak_hash' in backend/src/main/java/io/b2mash/b2b/b2bstrawman/billing/SubscriptionItnService.java:306"}, "fullDescription": {"text": "Found a known-risky pattern (weak_hash). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e55290efa28e19c7", "name": "Possible secret in backend/src/main/java/io/b2mash/b2b/b2bstrawman/accessrequest/AccessRequestApprovalService.java", "shortDescription": {"text": "Possible secret in backend/src/main/java/io/b2mash/b2b/b2bstrawman/accessrequest/AccessRequestApprovalService.java"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-645e19ad7523a311", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "aws-actions/amazon-ecr-login@v2 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": "medium", "confidence": 1.0}}, {"id": "scanner-c0d7e7ed5be2029c", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b84c425e625a51e0", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "JetBrains/qodana-action@v2025.3 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": "medium", "confidence": 1.0}}, {"id": "scanner-58220d7bfe0e9201", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1e355a8e6b2c4da8", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-36fd3c86ff87e5ff", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "aws-actions/amazon-ecr-login@v2 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": "medium", "confidence": 1.0}}, {"id": "scanner-a629b120390fd551", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2ede05f035b21f09", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "aws-actions/amazon-ecr-login@v2 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": "medium", "confidence": 1.0}}, {"id": "scanner-829b84e1a24994eb", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e53e9728a55338d8", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/github-script@v7 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-4466f36e7138c73e", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-64192a3c67110d01", "name": "GitHub Actions workflow grants broad write permissions", "shortDescription": {"text": "GitHub Actions workflow grants broad write permissions"}, "fullDescription": {"text": "CI tokens with write permissions increase blast radius when an action, dependency, or PR workflow is compromised. Prefer job-level least-privilege permissions."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5051f4fef5ed56f6", "name": "Very large file: compose/seed/lifecycle-test.sh (1363 lines)", "shortDescription": {"text": "Very large file: compose/seed/lifecycle-test.sh (1363 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-1323cf4b2203bdc0", "name": "Very large file: backend/src/test/java/io/b2mash/b2b/b2bstrawman/verticals/legal/trustaccounting/transaction/TrustTransa", "shortDescription": {"text": "Very large file: backend/src/test/java/io/b2mash/b2b/b2bstrawman/verticals/legal/trustaccounting/transaction/TrustTransactionServiceTest.java (2854 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-788dc785174012bd", "name": "Very large file: backend/src/test/java/io/b2mash/b2b/b2bstrawman/verticals/legal/statement/StatementOfAccountContextBuil", "shortDescription": {"text": "Very large file: backend/src/test/java/io/b2mash/b2b/b2bstrawman/verticals/legal/statement/StatementOfAccountContextBuilderTest.java (1257 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-f1abe885de95d90a", "name": "Very large file: backend/src/main/java/io/b2mash/b2b/b2bstrawman/verticals/legal/trustaccounting/transaction/TrustTransa", "shortDescription": {"text": "Very large file: backend/src/main/java/io/b2mash/b2b/b2bstrawman/verticals/legal/trustaccounting/transaction/TrustTransactionService.java (1411 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-b0b1d4079e3ea3ab", "name": "38 TODO/FIXME markers", "shortDescription": {"text": "38 TODO/FIXME markers"}, "fullDescription": {"text": "High count of TODO/FIXME/HACK markers \u2014 track them as issues so they're not forgotten."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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-0e8a76eb13fd3249", "name": "Node manifest has dependencies but no lockfile: frontend/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: frontend/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b8fae141f052f3ab", "name": "Node manifest has dependencies but no lockfile: docs/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: docs/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-50218c90b43393bb", "name": "Node manifest has dependencies but no lockfile: packages/ui/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/ui/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b27b66da6f566f2e", "name": "Node manifest has dependencies but no lockfile: portal/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: portal/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 7 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 666 placeholder/mock markers across 280 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-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, lockfile. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-122f91b7f2906dc4", "name": "Agent authority lacks a verifier contract: .claude/settings.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/settings.json"}, "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-d3b9a9717c505941", "name": "Agent authority lacks a verifier contract: .claude/ideas/template-extraction-ideation-2026-03-29.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/template-extraction-ideation-2026-03-29.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-11f60be1207ee6e7", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase62-ideation-2026-04-04.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase62-ideation-2026-04-04.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-1aa88ae00efbf155", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase29-ideation-2026-02-27.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase29-ideation-2026-02-27.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-42a74ab3f3ca84ff", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase45-ideation-2026-03-12.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase45-ideation-2026-03-12.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-c022b064aa1331a3", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase66-ideation-2026-04-17.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase66-ideation-2026-04-17.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-fe28812412665fed", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase44-ideation-2026-03-10.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase44-ideation-2026-03-10.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-e5010b862a4b0c1a", "name": "Agent authority lacks a verifier contract: .claude/ideas/branding-kazi-2026-03-22.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/branding-kazi-2026-03-22.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-8b4735d35169f3ba", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase68-ideation-2026-04-18.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase68-ideation-2026-04-18.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-3f36a5cb116e795d", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase75-ideation-2026-05-27.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase75-ideation-2026-05-27.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-197a9d18bf0644c0", "name": "Agent authority lacks a verifier contract: .claude/ideas/phase18-ideation-2026-02-20.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase18-ideation-2026-02-20.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-2f4db7418d2ef764", "name": "Agent instruction/config may expose a secret: infra/CLAUDE.md", "shortDescription": {"text": "Agent instruction/config may expose a secret: infra/CLAUDE.md"}, "fullDescription": {"text": "Agent-facing files are routinely pasted into LLM/tool contexts. Move literal tokens, keys, and passwords into a secret manager or document them as placeholders only."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-002a2c7843a51d57", "name": "Agent authority lacks a verifier contract: infra/CLAUDE.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: infra/CLAUDE.md"}, "fullDescription": {"text": "This agent instruction grants code or shell authority but does not state the verification gate that decides promotion. The recurring safe pattern is: LLM proposes; deterministic tests/build/security checks verify; only verified code promotes."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e725d2ab884fbd49", "name": "Multiple root agent instruction files without precedence", "shortDescription": {"text": "Multiple root agent instruction files without precedence"}, "fullDescription": {"text": "The repo has multiple top-level AI-coder instruction files. Without precedence rules, different agents may follow different policies."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-fc4789b6eb029d9a", "name": "Commented-code block (5 lines) in compose/keycloak/theme/src/login/pages/Register.tsx:17", "shortDescription": {"text": "Commented-code block (5 lines) in compose/keycloak/theme/src/login/pages/Register.tsx:17"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a3acac899be983cd", "name": "Commented-code block (5 lines) in frontend/__tests__/trust-coexistence.test.tsx:193", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/__tests__/trust-coexistence.test.tsx:193"}, "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-ed8b714eaa2a7fae", "name": "Commented-code block (5 lines) in frontend/__tests__/ai/execution-gate-card.test.tsx:28", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/__tests__/ai/execution-gate-card.test.tsx:28"}, "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-3cc330f82092cf57", "name": "Commented-code block (6 lines) in frontend/__tests__/field-definitions/CustomFieldSection.test.tsx:447", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/__tests__/field-definitions/CustomFieldSection.test.tsx:447"}, "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-d070f5f65449af26", "name": "Commented-code block (6 lines) in frontend/__tests__/components/dialog-family-ssr.snapshot.test.tsx:60", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/__tests__/components/dialog-family-ssr.snapshot.test.tsx:60"}, "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-29c1aeed351c696e", "name": "Commented-code block (7 lines) in frontend/__tests__/eslint-rules/no-aschild-adjacency.test.ts:195", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/__tests__/eslint-rules/no-aschild-adjacency.test.ts:195"}, "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-393cda710d5a23c0", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/sidebar-user-footer.tsx:74", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/sidebar-user-footer.tsx:74"}, "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-d8f17c6389373078", "name": "Commented-code block (5 lines) in frontend/components/legal/matter-closure-dialog.tsx:91", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/components/legal/matter-closure-dialog.tsx:91"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ffef40aaf533b794", "name": "Commented-code block (8 lines) in frontend/components/ai/execution-gate-card.tsx:72", "shortDescription": {"text": "Commented-code block (8 lines) in frontend/components/ai/execution-gate-card.tsx:72"}, "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-1210087865daacfc", "name": "Commented-code block (7 lines) in frontend/components/activity/activity-feed-client.tsx:37", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/components/activity/activity-feed-client.tsx:37"}, "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-83449fd3dd6c91a8", "name": "Commented-code block (5 lines) in frontend/components/dashboard/sensitive-events-widget.tsx:71", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/components/dashboard/sensitive-events-widget.tsx:71"}, "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-2cd41fff33c3b6da", "name": "Commented-code block (5 lines) in frontend/components/proposals/__tests__/create-proposal-dialog.test.tsx:152", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/components/proposals/__tests__/create-proposal-dialog.test.tsx:152"}, "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-71a47adba3d5b0d2", "name": "Commented-code block (5 lines) in frontend/components/customers/intake-fields-section.tsx:55", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/components/customers/intake-fields-section.tsx:55"}, "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-84011874eebd4be4", "name": "Commented-code block (7 lines) in frontend/components/customers/edit-customer-dialog.tsx:164", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/components/customers/edit-customer-dialog.tsx:164"}, "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-d324de7d81eb208e", "name": "Commented-code block (7 lines) in frontend/components/customers/create-customer-dialog.tsx:190", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/components/customers/create-customer-dialog.tsx:190"}, "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-6d0984a6217daea6", "name": "Commented-code block (9 lines) in frontend/components/billing-runs/cherry-pick-step.tsx:157", "shortDescription": {"text": "Commented-code block (9 lines) in frontend/components/billing-runs/cherry-pick-step.tsx:157"}, "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-5a1bdeebd0d2ea03", "name": "Commented-code block (6 lines) in frontend/components/assistant/specialist-panel.tsx:144", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/components/assistant/specialist-panel.tsx:144"}, "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-eebe1d4e331a8ad9", "name": "Legacy-named symbol `isLegacy` in frontend/components/clauses/clauses-content.tsx:288", "shortDescription": {"text": "Legacy-named symbol `isLegacy` in frontend/components/clauses/clauses-content.tsx:288"}, "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-cdf41190db14ec7b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/api/customers/route.ts:40", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/api/customers/route.ts:40"}, "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-768319ce73bf5f61", "name": "Commented-code block (8 lines) in frontend/app/(app)/org/[slug]/settings/audit-log/audit-log-client.tsx:292", "shortDescription": {"text": "Commented-code block (8 lines) in frontend/app/(app)/org/[slug]/settings/audit-log/audit-log-client.tsx:292"}, "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-1ac4d3b222c642ce", "name": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/projects/[id]/page.tsx:221", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/projects/[id]/page.tsx:221"}, "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-5e27c49ad710e03d", "name": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/projects/[id]/(tabs)/statements.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/projects/[id]/(tabs)/statements.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-a201674973511c44", "name": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/projects/[id]/(tabs)/disbursements.tsx:1", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/projects/[id]/(tabs)/disbursements.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-5084359d79ec16ff", "name": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/dashboard/page.tsx:106", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/dashboard/page.tsx:106"}, "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-2c79a0834ecd14cb", "name": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/trust-accounting/client-ledgers/[customerId]/page.tsx:17", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/trust-accounting/client-ledgers/[customerId]/page.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-1e023ad8123cfabf", "name": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/conflict-check/actions.ts:100", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/conflict-check/actions.ts:100"}, "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-dc22092596fb4908", "name": "Commented-code block (6 lines) in frontend/app/accept-invite/complete/page.tsx:14", "shortDescription": {"text": "Commented-code block (6 lines) in frontend/app/accept-invite/complete/page.tsx: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-08b27fb6caa67254", "name": "Commented-code block (5 lines) in frontend/lib/format.test.ts:33", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/lib/format.test.ts:33"}, "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-e022bdad6c97db43", "name": "Commented-code block (10 lines) in frontend/lib/format.ts:8", "shortDescription": {"text": "Commented-code block (10 lines) in frontend/lib/format.ts: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-f2352722a04d74d3", "name": "Commented-code block (7 lines) in frontend/lib/intl-polyfill.ts:11", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/lib/intl-polyfill.ts:11"}, "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-7d9b9c05e9c7d422", "name": "Commented-code block (7 lines) in frontend/lib/auth/middleware.ts:74", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/lib/auth/middleware.ts:74"}, "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-bb189fcc3ba39826", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/auth/client/hooks.ts:52", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/auth/client/hooks.ts:52"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9ff88290484a12cf", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/api/assistant-specialists.ts:147", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/api/assistant-specialists.ts:147"}, "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-cddb5d52c815682f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/api/portal-acceptance.ts:28", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/api/portal-acceptance.ts:28"}, "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-d9519f283a8343cd", "name": "Commented-code block (5 lines) in frontend/lib/schemas/ai-profile.ts:11", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/lib/schemas/ai-profile.ts:11"}, "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-0d7b9ba4c5a6a2a9", "name": "Commented-code block (5 lines) in frontend/eslint-rules/no-aschild-adjacency.mjs:81", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/eslint-rules/no-aschild-adjacency.mjs:81"}, "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-ca7e713835f1ded9", "name": "Commented-code block (5 lines) in frontend/e2e/tests/lifecycle-portal.spec.ts:123", "shortDescription": {"text": "Commented-code block (5 lines) in frontend/e2e/tests/lifecycle-portal.spec.ts:123"}, "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-4bf856757c878f23", "name": "Commented-code block (7 lines) in frontend/e2e/tests/audit-log/audit-log-smoke.spec.ts:39", "shortDescription": {"text": "Commented-code block (7 lines) in frontend/e2e/tests/audit-log/audit-log-smoke.spec.ts:39"}, "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-0292b74a94afe75d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/e2e/helpers/mailpit.ts:31", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/e2e/helpers/mailpit.ts:31"}, "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-bdf31024b3d4b3b8", "name": "Commented-code block (5 lines) in portal/app/(authenticated)/layout.tsx:30", "shortDescription": {"text": "Commented-code block (5 lines) in portal/app/(authenticated)/layout.tsx:30"}, "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-9d14200ebd5ef9af", "name": "`fetch()` without try/.catch or AbortSignal \u2014 portal/app/(authenticated)/requests/[id]/page.tsx:146", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 portal/app/(authenticated)/requests/[id]/page.tsx:146"}, "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-c61c9dd83b7b85d2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 portal/lib/api-client.ts:24", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 portal/lib/api-client.ts:24"}, "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-fcb53d1fa9b62a6f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 portal/e2e/helpers/auth.ts:42", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 portal/e2e/helpers/auth.ts:42"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d6ffa20a9f1093b", "name": "24 env vars used in code but missing from .env.example", "shortDescription": {"text": "24 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BACKEND_URL`, `BASE_URL`, `CI`, `E2E_AUTH_MODE`, `GATEWAY_URL`, `MAILPIT_URL`, `MOCK_IDP_URL`, `MOCK_USERS` + 16 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0ba36a1996fe8b89", "name": "Dangling fetch: GET http://localhost:8025/api/v1/messages?limit=20 (frontend/e2e/tests/debug-kc-invite.spec.ts:15)", "shortDescription": {"text": "Dangling fetch: GET http://localhost:8025/api/v1/messages?limit=20 (frontend/e2e/tests/debug-kc-invite.spec.ts:15)"}, "fullDescription": {"text": "`frontend/e2e/tests/debug-kc-invite.spec.ts:15` calls `GET http://localhost:8025/api/v1/messages?limit=20` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:8025/api/v1/messages`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-358815753e8867f1", "name": "Unused endpoint: POST /token", "shortDescription": {"text": "Unused endpoint: POST /token"}, "fullDescription": {"text": "`compose/mock-idp/src/index.ts` declares `POST /token` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6d2796cd3a798a38", "name": "Unused endpoint: GET /userinfo/:userId", "shortDescription": {"text": "Unused endpoint: GET /userinfo/:userId"}, "fullDescription": {"text": "`compose/mock-idp/src/index.ts` declares `GET /userinfo/:userId` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e4baedd96af08af8", "name": "Unused endpoint: GET /api/customers", "shortDescription": {"text": "Unused endpoint: GET /api/customers"}, "fullDescription": {"text": "`frontend/app/api/customers/route.ts` declares `GET /api/customers` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-76eff11be61f4d88", "name": "Unused endpoint: PATCH /api/settings/tax", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/tax"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/tax/actions.ts` declares `PATCH /api/settings/tax` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7ac24a7e5b911b52", "name": "Unused endpoint: POST /api/field-definitions", "shortDescription": {"text": "Unused endpoint: POST /api/field-definitions"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/custom-fields/actions.ts` declares `POST /api/field-definitions` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dd1e40cf89039288", "name": "Unused endpoint: POST /api/field-groups", "shortDescription": {"text": "Unused endpoint: POST /api/field-groups"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/custom-fields/actions.ts` declares `POST /api/field-groups` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-71b1c31364b9649d", "name": "Unused endpoint: PATCH /api/settings/capacity", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/capacity"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/capacity/actions.ts` declares `PATCH /api/settings/capacity` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ed0899d50d0562bd", "name": "Unused endpoint: PATCH /api/settings/time-reminders", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/time-reminders"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/time-tracking/actions.ts` declares `PATCH /api/settings/time-reminders` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2b56ef9335731725", "name": "Unused endpoint: PATCH /api/settings/expense", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/expense"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/time-tracking/actions.ts` declares `PATCH /api/settings/expense` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3dd370eeae28c923", "name": "Unused endpoint: PATCH /api/settings/compliance", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/compliance"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/compliance/actions.ts` declares `PATCH /api/settings/compliance` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1280d33b4e27231c", "name": "Unused endpoint: PATCH /api/settings/request-reminders", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/request-reminders"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/request-settings/actions.ts` declares `PATCH /api/settings/request-reminders` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-57682006b1eca788", "name": "Unused endpoint: PATCH /api/settings/acceptance", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/acceptance"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/acceptance/actions.ts` declares `PATCH /api/settings/acceptance` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-60bd9b54df98bfcb", "name": "Unused endpoint: PATCH /api/settings/portal-digest-cadence", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/portal-digest-cadence"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/general/portal-actions.ts` declares `PATCH /api/settings/portal-digest-cadence` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3338eac1e1d0b54a", "name": "Unused endpoint: PATCH /api/settings/portal-retainer-member-display", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/portal-retainer-member-display"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/general/portal-actions.ts` declares `PATCH /api/settings/portal-retainer-member-display` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2bffc2596a61e55e", "name": "Unused endpoint: PUT /api/settings", "shortDescription": {"text": "Unused endpoint: PUT /api/settings"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/general/actions.ts` declares `PUT /api/settings` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-5649620c4f5d8fd5", "name": "Unused endpoint: PATCH /api/settings/batch-billing", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/batch-billing"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/batch-billing/actions.ts` declares `PATCH /api/settings/batch-billing` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4b1a3bafba0cad37", "name": "Unused endpoint: PATCH /api/settings/data-protection", "shortDescription": {"text": "Unused endpoint: PATCH /api/settings/data-protection"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/settings/data-protection/actions.ts` declares `PATCH /api/settings/data-protection` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b7f4f733e8f8d79b", "name": "Unused endpoint: POST /api/tariff-schedules", "shortDescription": {"text": "Unused endpoint: POST /api/tariff-schedules"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/legal/tariffs/actions.ts` declares `POST /api/tariff-schedules` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-d4e00f2da0b7247d", "name": "Unused endpoint: POST /api/adverse-parties", "shortDescription": {"text": "Unused endpoint: POST /api/adverse-parties"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/legal/adverse-parties/actions.ts` declares `POST /api/adverse-parties` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b581d162f3110245", "name": "Unused endpoint: POST /api/court-dates", "shortDescription": {"text": "Unused endpoint: POST /api/court-dates"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/court-calendar/actions.ts` declares `POST /api/court-dates` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c5e2b78e3737e653", "name": "Unused endpoint: POST /api/prescription-trackers", "shortDescription": {"text": "Unused endpoint: POST /api/prescription-trackers"}, "fullDescription": {"text": "`frontend/app/(app)/org/[slug]/court-calendar/actions.ts` declares `POST /api/prescription-trackers` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-21ea290201446de7", "name": "Unused endpoint: POST /api/onboarding/dismiss", "shortDescription": {"text": "Unused endpoint: POST /api/onboarding/dismiss"}, "fullDescription": {"text": "`frontend/lib/actions/onboarding.ts` declares `POST /api/onboarding/dismiss` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b2b0f779852d3f04", "name": "Unused endpoint: POST /api/clauses", "shortDescription": {"text": "Unused endpoint: POST /api/clauses"}, "fullDescription": {"text": "`frontend/lib/actions/clause-actions.ts` declares `POST /api/clauses` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-95cfb69015fb6517", "name": "Unused endpoint: PUT /api/notifications/read-all", "shortDescription": {"text": "Unused endpoint: PUT /api/notifications/read-all"}, "fullDescription": {"text": "`frontend/lib/actions/notifications.ts` declares `PUT /api/notifications/read-all` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b3bc4a685cc0f734", "name": "Unused endpoint: PUT /api/settings/modules", "shortDescription": {"text": "Unused endpoint: PUT /api/settings/modules"}, "fullDescription": {"text": "`frontend/lib/actions/module-settings.ts` declares `PUT /api/settings/modules` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/17851"}, "properties": {"repository": "rakheen-dama/b2b-strawman", "repoUrl": "https://github.com/rakheen-dama/b2b-strawman", "branch": "main"}, "results": [{"ruleId": "scanner-15974498ea95a716", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 compose/mock-idp/src/index.ts:90"}, "properties": {"repobilityId": "0f2c70177bca99c5", "scanner": "scanner-primary", "fingerprint": "15974498ea95a716", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7a6fe9a25cca0fe6", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginUsername.tsx:26"}, "properties": {"repobilityId": "0cedea62705b0ab4", "scanner": "scanner-primary", "fingerprint": "7a6fe9a25cca0fe6", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-c9c8e611fa2b5f26", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx:31"}, "properties": {"repobilityId": "c940417feacd30af", "scanner": "scanner-primary", "fingerprint": "c9c8e611fa2b5f26", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-1177e75f39127594", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/LoginPassword.tsx:26"}, "properties": {"repobilityId": "adb6f2eee409e1b2", "scanner": "scanner-primary", "fingerprint": "1177e75f39127594", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-90ac53883eb5887a", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Error.tsx:39"}, "properties": {"repobilityId": "717da998c3a5be8a", "scanner": "scanner-primary", "fingerprint": "90ac53883eb5887a", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-593b0a4808fe41c6", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Login.tsx:26"}, "properties": {"repobilityId": "161fe9871318e475", "scanner": "scanner-primary", "fingerprint": "593b0a4808fe41c6", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-26701620bb8655e2", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Register.tsx:29"}, "properties": {"repobilityId": "45eac74a824d394b", "scanner": "scanner-primary", "fingerprint": "26701620bb8655e2", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-9b90c70affe928f0", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 compose/keycloak/theme/src/login/pages/Info.tsx:29"}, "properties": {"repobilityId": "6e35cd7ed49206b3", "scanner": "scanner-primary", "fingerprint": "9b90c70affe928f0", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-235fbef46eb9baca", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/sidebar-user-footer.tsx:58"}, "properties": {"repobilityId": "248508a38c6c4f0b", "scanner": "scanner-primary", "fingerprint": "235fbef46eb9baca", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-58ee246c6a98803a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/mobile-sidebar.tsx:74"}, "properties": {"repobilityId": "0252cbbf5109b8dd", "scanner": "scanner-primary", "fingerprint": "58ee246c6a98803a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-66c972fe4359beff", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/desktop-sidebar.tsx:75"}, "properties": {"repobilityId": "75dee71967c4237d", "scanner": "scanner-primary", "fingerprint": "66c972fe4359beff", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2273e39437db80ff", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth-header-controls.tsx:24"}, "properties": {"repobilityId": "f5937f90ecd3f3c8", "scanner": "scanner-primary", "fingerprint": "2273e39437db80ff", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eaf363f32cf73698", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/settings/org-documents-section.tsx:111"}, "properties": {"repobilityId": "a8bfdb5b5f5e3ee0", "scanner": "scanner-primary", "fingerprint": "eaf363f32cf73698", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-23f1d0ce2f46a935", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/disbursement-list-view.tsx:200"}, "properties": {"repobilityId": "a89dceabf579e2ec", "scanner": "scanner-primary", "fingerprint": "23f1d0ce2f46a935", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0899cb2c96952a41", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/upcoming-court-dates-widget.tsx:126"}, "properties": {"repobilityId": "b9a90a6192887df8", "scanner": "scanner-primary", "fingerprint": "0899cb2c96952a41", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-23a1c4aaaf4c488c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/legal/tariff-line-dialog.tsx:208"}, "properties": {"repobilityId": "bd566c2112062c7d", "scanner": "scanner-primary", "fingerprint": "23a1c4aaaf4c488c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c172189ca2584c9d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/ai/compliance-finding-list.tsx:194"}, "properties": {"repobilityId": "2d2d229555a9141d", "scanner": "scanner-primary", "fingerprint": "c172189ca2584c9d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8c9be3ca4806edb7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/ai/contract-review-results.tsx:69"}, "properties": {"repobilityId": "6fe82ebede981991", "scanner": "scanner-primary", "fingerprint": "8c9be3ca4806edb7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-522dbc07ff67fff4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/mock-org-switcher.tsx:12"}, "properties": {"repobilityId": "aa4f64f9554d0eb2", "scanner": "scanner-primary", "fingerprint": "522dbc07ff67fff4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b6fedb5005ac6285", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/mock-user-button.tsx:45"}, "properties": {"repobilityId": "50d29f111a0de0a3", "scanner": "scanner-primary", "fingerprint": "b6fedb5005ac6285", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9b52f61a8d1f037d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/auth/user-menu-bff.tsx:143"}, "properties": {"repobilityId": "e29c3d966c39f514", "scanner": "scanner-primary", "fingerprint": "9b52f61a8d1f037d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa7c62f7970a0c75", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/project-members-panel.tsx:178"}, "properties": {"repobilityId": "c5ea08d103890eb2", "scanner": "scanner-primary", "fingerprint": "fa7c62f7970a0c75", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c7ac80aad3eb543e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/add-member-dialog.tsx:131"}, "properties": {"repobilityId": "19a9722b90720999", "scanner": "scanner-primary", "fingerprint": "c7ac80aad3eb543e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f51e5f1bc5e179c5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/link-customer-dialog.tsx:126"}, "properties": {"repobilityId": "b723bb7f0e51215d", "scanner": "scanner-primary", "fingerprint": "f51e5f1bc5e179c5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e29bde87b127cfa1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/projects/upcoming-deadlines-tile.tsx:38"}, "properties": {"repobilityId": "b92640d2cc6e0ba0", "scanner": "scanner-primary", "fingerprint": "e29bde87b127cfa1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8995c8c287c566a4", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/activity/activity-feed-client.tsx:40"}, "properties": {"repobilityId": "fc3e94af5ae71193", "scanner": "scanner-primary", "fingerprint": "8995c8c287c566a4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-374dc6a64b81d8b2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/recent-activity-widget.tsx:108"}, "properties": {"repobilityId": "cb631ddb0fe6ec4a", "scanner": "scanner-primary", "fingerprint": "374dc6a64b81d8b2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0e943d5563ea49d4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/incomplete-profiles-widget.tsx:84"}, "properties": {"repobilityId": "2eb0e0c9637ddaa7", "scanner": "scanner-primary", "fingerprint": "0e943d5563ea49d4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-df63eb3f68ac4bbe", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/my-schedule-widget.tsx:73"}, "properties": {"repobilityId": "6984978459addea4", "scanner": "scanner-primary", "fingerprint": "df63eb3f68ac4bbe", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c65230e8a0272bd9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/sensitive-events-widget.tsx:140"}, "properties": {"repobilityId": "8eebcee7ab726e3c", "scanner": "scanner-primary", "fingerprint": "c65230e8a0272bd9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0fde7cee00798054", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/project-health-widget.tsx:192"}, "properties": {"repobilityId": "8218a8c60d8f32df", "scanner": "scanner-primary", "fingerprint": "0fde7cee00798054", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0d74f2d3c9b8c11e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/my-week-column.tsx:47"}, "properties": {"repobilityId": "8732d46a579f6417", "scanner": "scanner-primary", "fingerprint": "0d74f2d3c9b8c11e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-88ef603843b704b2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/dashboard/todays-agenda.tsx:60"}, "properties": {"repobilityId": "a26877dda537b1b9", "scanner": "scanner-primary", "fingerprint": "88ef603843b704b2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6ccf9193573135ff", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/proposals/create-proposal-dialog.tsx:295"}, "properties": {"repobilityId": "6947021f614fd653", "scanner": "scanner-primary", "fingerprint": "6ccf9193573135ff", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8c0de58332381466", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/rates/member-rates-table.tsx:186"}, "properties": {"repobilityId": "759f98b06d21f1f1", "scanner": "scanner-primary", "fingerprint": "8c0de58332381466", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3c0b00a158f8c793", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/capacity/allocation-popover.tsx:178"}, "properties": {"repobilityId": "4801dc296a2742bb", "scanner": "scanner-primary", "fingerprint": "3c0b00a158f8c793", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e32246051b2bfca3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/time-tracking/weekly-time-grid.tsx:493"}, "properties": {"repobilityId": "9b7837cb0a9ec26e", "scanner": "scanner-primary", "fingerprint": "e32246051b2bfca3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9e1027d7b0d34d85", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/customers/link-project-dialog.tsx:123"}, "properties": {"repobilityId": "1f566d5b71bbf5ad", "scanner": "scanner-primary", "fingerprint": "9e1027d7b0d34d85", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-37d7794bf2e32424", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/audit/audit-timeline.tsx:161"}, "properties": {"repobilityId": "48946ac8f9b2109f", "scanner": "scanner-primary", "fingerprint": "37d7794bf2e32424", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa1bf2af9b8a29fa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/TemplatePreviewDialog.tsx:203"}, "properties": {"repobilityId": "94b0846c2c39721d", "scanner": "scanner-primary", "fingerprint": "fa1bf2af9b8a29fa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f974787e0812d937", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/clause-picker-dialog.tsx:217"}, "properties": {"repobilityId": "c181d14166c2c8ee", "scanner": "scanner-primary", "fingerprint": "f974787e0812d937", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5f9d309c171daab9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/TemplatePicker.tsx:42"}, "properties": {"repobilityId": "ac7d0e07afd33a07", "scanner": "scanner-primary", "fingerprint": "5f9d309c171daab9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7d2598797edce5c8", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/templates/generation-clause-step.tsx:281"}, "properties": {"repobilityId": "686266f5f14a5698", "scanner": "scanner-primary", "fingerprint": "7d2598797edce5c8", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4d6fb34e253b0beb", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/components/templates/generation-clause-step.tsx:309"}, "properties": {"repobilityId": "1622f369124a8c2c", "scanner": "scanner-primary", "fingerprint": "4d6fb34e253b0beb", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-a038dbc571e03144", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/templates/TemplateEditorClient.tsx:4"}, "properties": {"repobilityId": "65eeda82ab517d6e", "scanner": "scanner-primary", "fingerprint": "a038dbc571e03144", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-026760ef21e73f97", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/assignee-selector.tsx:93"}, "properties": {"repobilityId": "16e88ed5559519e2", "scanner": "scanner-primary", "fingerprint": "026760ef21e73f97", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-05f1e7a8c01799b2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/task-list-table-row.tsx:114"}, "properties": {"repobilityId": "d13cb7729783fee4", "scanner": "scanner-primary", "fingerprint": "05f1e7a8c01799b2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6bf4b1a1c56d1825", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/tasks/time-entry-list.tsx:196"}, "properties": {"repobilityId": "3eaaa47ad4af33fd", "scanner": "scanner-primary", "fingerprint": "6bf4b1a1c56d1825", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-628fcb96dec4db49", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/compliance/CreateDataRequestDialog.tsx:189"}, "properties": {"repobilityId": "89a1a5dd04bee28c", "scanner": "scanner-primary", "fingerprint": "628fcb96dec4db49", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ed2d878a26bc087c", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/billing-runs/billing-run-wizard.tsx:31"}, "properties": {"repobilityId": "f1a751be608de02b", "scanner": "scanner-primary", "fingerprint": "ed2d878a26bc087c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-2723eca69d4f1721", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/billing-runs/configure-step.tsx:43"}, "properties": {"repobilityId": "3909d710d642b754", "scanner": "scanner-primary", "fingerprint": "2723eca69d4f1721", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-b970aacfb380d3a2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/expenses/expense-list.tsx:281"}, "properties": {"repobilityId": "3a842d040dbffdec", "scanner": "scanner-primary", "fingerprint": "b970aacfb380d3a2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1f19ca2024c1a7c2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/expenses/log-expense-dialog.tsx:363"}, "properties": {"repobilityId": "c15bc6918d9d58c8", "scanner": "scanner-primary", "fingerprint": "1f19ca2024c1a7c2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d9c7b0778555fcb9", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/assistant/specialist-panel.tsx:148"}, "properties": {"repobilityId": "337b2623df67420e", "scanner": "scanner-primary", "fingerprint": "d9c7b0778555fcb9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-e5211ee6e1e711bf", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/trust/TrustEntityPickers.tsx:104"}, "properties": {"repobilityId": "08624d9b44e850ab", "scanner": "scanner-primary", "fingerprint": "e5211ee6e1e711bf", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c69dbebc53eb7327", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/trust/ReconciliationSplitPane.tsx:192"}, "properties": {"repobilityId": "1b476e96182e0abb", "scanner": "scanner-primary", "fingerprint": "c69dbebc53eb7327", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3156d7ab09321026", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/portal/portal-document-table.tsx:98"}, "properties": {"repobilityId": "6ca0eb8c05ae1e41", "scanner": "scanner-primary", "fingerprint": "3156d7ab09321026", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f248bfba2401d234", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/components/editor/EditorToolbar.tsx:174"}, "properties": {"repobilityId": "50458ffd99b46388", "scanner": "scanner-primary", "fingerprint": "f248bfba2401d234", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-a440acbe916d0b34", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/EntityPicker.tsx:171"}, "properties": {"repobilityId": "d226b469a641fdab", "scanner": "scanner-primary", "fingerprint": "a440acbe916d0b34", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6ae8283c0ab437bd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/ClausePicker.tsx:168"}, "properties": {"repobilityId": "8c36fa862b349f56", "scanner": "scanner-primary", "fingerprint": "6ae8283c0ab437bd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-dc8ae43cb6a68c48", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/node-views/ClauseBlockNodeView.tsx:41"}, "properties": {"repobilityId": "dcd9e7de7d249374", "scanner": "scanner-primary", "fingerprint": "dc8ae43cb6a68c48", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5958a0615ffee02b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/editor/node-views/ConditionalBlockNodeView.tsx:35"}, "properties": {"repobilityId": "6bb70f91dfcaea78", "scanner": "scanner-primary", "fingerprint": "5958a0615ffee02b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7933082d580b17aa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/urgency-task-list.tsx:169"}, "properties": {"repobilityId": "d8d71a2016cf13f9", "scanner": "scanner-primary", "fingerprint": "7933082d580b17aa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b1d6197d097a22c4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/weekly-time-summary.tsx:155"}, "properties": {"repobilityId": "cc10400701537be4", "scanner": "scanner-primary", "fingerprint": "b1d6197d097a22c4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-44fe340ca3a58beb", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/today-time-entries.tsx:47"}, "properties": {"repobilityId": "a1259821be441994", "scanner": "scanner-primary", "fingerprint": "44fe340ca3a58beb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f785b64a4b55007d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/available-task-list.tsx:114"}, "properties": {"repobilityId": "956ca01de00688c8", "scanner": "scanner-primary", "fingerprint": "f785b64a4b55007d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-93830dab94ed671e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/my-expenses.tsx:51"}, "properties": {"repobilityId": "4f763c731983888a", "scanner": "scanner-primary", "fingerprint": "93830dab94ed671e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-35892a6cc0ae15a1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/my-work/assigned-task-list.tsx:123"}, "properties": {"repobilityId": "e9d760ba4a1e7caa", "scanner": "scanner-primary", "fingerprint": "35892a6cc0ae15a1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5addf6020cb8eb93", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/upload-progress-item.tsx:60"}, "properties": {"repobilityId": "b95f1fa74db984ff", "scanner": "scanner-primary", "fingerprint": "5addf6020cb8eb93", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e9faa1db8135216c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/customer-documents-panel.tsx:130"}, "properties": {"repobilityId": "6924afc693716ae0", "scanner": "scanner-primary", "fingerprint": "e9faa1db8135216c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d378c79f112f107e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/documents/documents-panel.tsx:465"}, "properties": {"repobilityId": "1761250636bcce3e", "scanner": "scanner-primary", "fingerprint": "d378c79f112f107e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e4b111fd7a3712d6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/clauses/clauses-content.tsx:376"}, "properties": {"repobilityId": "7524df2c6e84541e", "scanner": "scanner-primary", "fingerprint": "e4b111fd7a3712d6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a717fa859745c42b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/data-protection/processing-register-table.tsx:374"}, "properties": {"repobilityId": "371e3fb11d0e9a79", "scanner": "scanner-primary", "fingerprint": "a717fa859745c42b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bc14baa48b979333", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/components/retainers/create-retainer-dialog.tsx:195"}, "properties": {"repobilityId": "f19cc715b0b8b649", "scanner": "scanner-primary", "fingerprint": "bc14baa48b979333", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9453e38b3a0a0d6d", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 frontend/app/portal/(authenticated)/proposals/[id]/page.tsx:315"}, "properties": {"repobilityId": "df8721dfc810822e", "scanner": "scanner-primary", "fingerprint": "9453e38b3a0a0d6d", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-12beddd71267ed6f", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/platform-admin/demo/actions.ts:61"}, "properties": {"repobilityId": "44c804ac0f061e41", "scanner": "scanner-primary", "fingerprint": "12beddd71267ed6f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-0e7f9f020f6afd90", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/layout.tsx:90"}, "properties": {"repobilityId": "48559cc0ab441127", "scanner": "scanner-primary", "fingerprint": "0e7f9f020f6afd90", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-47c650eaf3f65324", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/settings/integrations/xero/sync-log/actions.ts:72"}, "properties": {"repobilityId": "a6557053fd06c167", "scanner": "scanner-primary", "fingerprint": "47c650eaf3f65324", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-f894f8aee3847e39", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/settings/audit-log/audit-log-client.tsx:299"}, "properties": {"repobilityId": "002151bc403fbdcd", "scanner": "scanner-primary", "fingerprint": "f894f8aee3847e39", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-02971978a90ff3ac", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/settings/templates/FieldDiscoveryResults.tsx:26"}, "properties": {"repobilityId": "3004f37da42c2b94", "scanner": "scanner-primary", "fingerprint": "02971978a90ff3ac", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a6e31e17dc971576", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/legal/disbursements/[id]/detail-client.tsx:215"}, "properties": {"repobilityId": "09cbe380fda0beb0", "scanner": "scanner-primary", "fingerprint": "a6e31e17dc971576", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-51edbd87edd04a5a", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/projects/[id]/page.tsx:107"}, "properties": {"repobilityId": "73a8b61edcb40801", "scanner": "scanner-primary", "fingerprint": "51edbd87edd04a5a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-13f79f501dd1f04a", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/projects/[id]/statement-actions.ts:55"}, "properties": {"repobilityId": "d64cc691b3bb6729", "scanner": "scanner-primary", "fingerprint": "13f79f501dd1f04a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-be7105c9b3e49959", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/trust-accounting/actions.ts:84"}, "properties": {"repobilityId": "7ce02fe327259a0d", "scanner": "scanner-primary", "fingerprint": "be7105c9b3e49959", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-6977498df71ad273", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/app/(app)/org/[slug]/trust-accounting/reconciliation/new/page.tsx:159"}, "properties": {"repobilityId": "6d74f5c2df907d1a", "scanner": "scanner-primary", "fingerprint": "6977498df71ad273", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-7461e4051b8caee0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/calendar/calendar-list-view.tsx:110"}, "properties": {"repobilityId": "1dee0142e022b501", "scanner": "scanner-primary", "fingerprint": "7461e4051b8caee0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-13195bfe611fd535", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 frontend/app/(app)/org/[slug]/calendar/calendar-month-view.tsx:221"}, "properties": {"repobilityId": "ee43899a1bc41e33", "scanner": "scanner-primary", "fingerprint": "13195bfe611fd535", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3c524cd6f5d0402a", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/lib/compliance-api.ts:101"}, "properties": {"repobilityId": "0453229c15356848", "scanner": "scanner-primary", "fingerprint": "3c524cd6f5d0402a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-8f4fca88e43d8b3b", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/lib/messages/index.ts:32"}, "properties": {"repobilityId": "08a13f230ed3b7d7", "scanner": "scanner-primary", "fingerprint": "8f4fca88e43d8b3b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-b9a455a715181b8b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 frontend/e2e/tests/debug-kc-invite.spec.ts:17"}, "properties": {"repobilityId": "7a7b935206266e67", "scanner": "scanner-primary", "fingerprint": "b9a455a715181b8b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b24588d50d42660c", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/e2e/tests/admin-audit-30day/fixtures.ts:121"}, "properties": {"repobilityId": "fd2cabf753746868", "scanner": "scanner-primary", "fingerprint": "b24588d50d42660c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-c90d7c628ee40a88", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 frontend/e2e/tests/specialists/billing-launcher.spec.ts:30"}, "properties": {"repobilityId": "c2826dec8df45279", "scanner": "scanner-primary", "fingerprint": "c90d7c628ee40a88", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-ae10ecab1872c96e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/portal-sidebar.tsx:69"}, "properties": {"repobilityId": "e566a3af47b84674", "scanner": "scanner-primary", "fingerprint": "ae10ecab1872c96e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9c911c930f24e524", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/portal-topbar.tsx:60"}, "properties": {"repobilityId": "7b10800c4ce060a2", "scanner": "scanner-primary", "fingerprint": "9c911c930f24e524", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-aedb51b6b451cc8d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/document-list.tsx:57"}, "properties": {"repobilityId": "7f087e64a64974d2", "scanner": "scanner-primary", "fingerprint": "aedb51b6b451cc8d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-76e74767e48a8196", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/pending-acceptances-list.tsx:111"}, "properties": {"repobilityId": "512b4858ad2bd426", "scanner": "scanner-primary", "fingerprint": "76e74767e48a8196", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a58b2879a17723b0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/components/deadlines/deadline-list.tsx:287"}, "properties": {"repobilityId": "9f95736860bee6ff", "scanner": "scanner-primary", "fingerprint": "a58b2879a17723b0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8a67d7ca6b1203a4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/app/(authenticated)/proposals/page.tsx:136"}, "properties": {"repobilityId": "8f7995396a539f25", "scanner": "scanner-primary", "fingerprint": "8a67d7ca6b1203a4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fb6436ddfdef8feb", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 portal/app/(authenticated)/proposals/[id]/page.tsx:278"}, "properties": {"repobilityId": "565120eda29ceb19", "scanner": "scanner-primary", "fingerprint": "fb6436ddfdef8feb", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-3cc26715a25121c1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 portal/app/(authenticated)/trust/[matterId]/page.tsx:238"}, "properties": {"repobilityId": "110ad9522b6eb093", "scanner": "scanner-primary", "fingerprint": "3cc26715a25121c1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fca7b196884fed0c", "level": "warning", "message": {"text": "Privileged port 28 in use"}, "properties": {"repobilityId": "5c3f00b3e839840d", "scanner": "scanner-primary", "fingerprint": "fca7b196884fed0c", "layer": "network", "severity": "medium", "confidence": 1.0, "tags": ["security", "ports"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "qa_cycle/_archive_2026-04-30_legal-clean-slate/checkpoint-results/day-02-conflict-check-clear.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-397746cf43b3c83f", "level": "warning", "message": {"text": "Dockerfile runs as root: compose/mock-idp/Dockerfile"}, "properties": {"repobilityId": "31e8bf10abc33af2", "scanner": "scanner-primary", "fingerprint": "397746cf43b3c83f", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-3104e147acce2251", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "56ba6885287310fa", "scanner": "scanner-primary", "fingerprint": "3104e147acce2251", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/mock-idp/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3104e147acce2251", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "ea33d51564d3736c", "scanner": "scanner-primary", "fingerprint": "3104e147acce2251", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/mock-idp/Dockerfile"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-03ae6e174e16a97e", "level": "warning", "message": {"text": "Dockerfile runs as root: compose/seed/Dockerfile"}, "properties": {"repobilityId": "9ed09f53e0b3d31c", "scanner": "scanner-primary", "fingerprint": "03ae6e174e16a97e", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-fe4b01d6b0bc2703", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: alpine:3.19"}, "properties": {"repobilityId": "5e3390f82ae1b117", "scanner": "scanner-primary", "fingerprint": "fe4b01d6b0bc2703", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/seed/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "f0f6dcbc34a2a6cb", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "cbd2502d21e25d1c", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-faa134129e5545ff", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "1c3680267ec52020", "scanner": "scanner-primary", "fingerprint": "faa134129e5545ff", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/Dockerfile"}, "region": {"startLine": 59}}}]}, {"ruleId": "scanner-20bd6afcf637e243", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "275c716d5719a3b7", "scanner": "scanner-primary", "fingerprint": "20bd6afcf637e243", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "portal/Dockerfile"}, "region": {"startLine": 6}}}]}, {"ruleId": "scanner-20bd6afcf637e243", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "ce2540f4eaec650b", "scanner": "scanner-primary", "fingerprint": "20bd6afcf637e243", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "portal/Dockerfile"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-20bd6afcf637e243", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "56bf146da0016a6f", "scanner": "scanner-primary", "fingerprint": "20bd6afcf637e243", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "portal/Dockerfile"}, "region": {"startLine": 51}}}]}, {"ruleId": "scanner-4f0add5abd530738", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jdk"}, "properties": {"repobilityId": "55874388a00101d7", "scanner": "scanner-primary", "fingerprint": "4f0add5abd530738", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "gateway/Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-1a4540a7258d1030", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jre-alpine"}, "properties": {"repobilityId": "0089122548206322", "scanner": "scanner-primary", "fingerprint": "1a4540a7258d1030", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "gateway/Dockerfile"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-e011d9f144b0dc64", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jdk"}, "properties": {"repobilityId": "f6da950bdfd9c07c", "scanner": "scanner-primary", "fingerprint": "e011d9f144b0dc64", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/Dockerfile"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-11f8caef0be4bb43", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: eclipse-temurin:25-jre-alpine"}, "properties": {"repobilityId": "4667db18129fcf61", "scanner": "scanner-primary", "fingerprint": "11f8caef0be4bb43", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/Dockerfile"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-aa5acaa49eb8315b", "level": "note", "message": {"text": "Containers defined but no K8s/orchestration manifest found"}, "properties": {"repobilityId": "b230ea9b68736081", "scanner": "scanner-primary", "fingerprint": "aa5acaa49eb8315b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["coverage", "deployment"]}}, {"ruleId": "scanner-fc28be289986701a", "level": "error", "message": {"text": "Runtime dotenv file present in repo: compose/.env.keycloak"}, "properties": {"repobilityId": "f0ce7bfbe5e4a02a", "scanner": "scanner-primary", "fingerprint": "fc28be289986701a", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets", "config", "env-file", "runtime-env", "env_file_with_secret"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/.env.keycloak"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5f3bd1a7930440da", "level": "error", "message": {"text": "Runtime dotenv file present in repo: frontend/.env.keycloak"}, "properties": {"repobilityId": "dedc6b4e94ee0bfb", "scanner": "scanner-primary", "fingerprint": "5f3bd1a7930440da", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets", "config", "env-file", "runtime-env", "env_file_with_secret"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/.env.keycloak"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c5f94cff05775af9", "level": "error", "message": {"text": "Possible secret in compose/scripts/keycloak-bootstrap.sh"}, "properties": {"repobilityId": "883ed769ea4031cb", "scanner": "scanner-primary", "fingerprint": "c5f94cff05775af9", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/scripts/keycloak-bootstrap.sh"}, "region": {"startLine": 254}}}]}, {"ruleId": "scanner-e6645361781748b5", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in compose/mock-idp/src/index.ts:11"}, "properties": {"repobilityId": "4f890d7c4ce038b6", "scanner": "scanner-primary", "fingerprint": "e6645361781748b5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/mock-idp/src/index.ts"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-4bed4205e408a488", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginUsername.tsx:26"}, "properties": {"repobilityId": "3aa105849f39d158", "scanner": "scanner-primary", "fingerprint": "4bed4205e408a488", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/LoginUsername.tsx"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-732108c9d3980c0a", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx:31"}, "properties": {"repobilityId": "f1b0ea6a3e2cee7e", "scanner": "scanner-primary", "fingerprint": "732108c9d3980c0a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/LoginResetPassword.tsx"}, "region": {"startLine": 31}}}]}, {"ruleId": "scanner-93c155e6b02942f7", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/LoginPassword.tsx:26"}, "properties": {"repobilityId": "9b95278300c34504", "scanner": "scanner-primary", "fingerprint": "93c155e6b02942f7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/LoginPassword.tsx"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-d51c8f6d2e61e291", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Error.tsx:39"}, "properties": {"repobilityId": "f424a4f70b8a4803", "scanner": "scanner-primary", "fingerprint": "d51c8f6d2e61e291", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/Error.tsx"}, "region": {"startLine": 39}}}]}, {"ruleId": "scanner-238a95d19252d36e", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Login.tsx:26"}, "properties": {"repobilityId": "747206e809bc1ebe", "scanner": "scanner-primary", "fingerprint": "238a95d19252d36e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/Login.tsx"}, "region": {"startLine": 26}}}]}, {"ruleId": "scanner-10c7903b84a7d762", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Register.tsx:29"}, "properties": {"repobilityId": "ff6c385cc0c0e675", "scanner": "scanner-primary", "fingerprint": "10c7903b84a7d762", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/Register.tsx"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-e16d2bc412d091ed", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in compose/keycloak/theme/src/login/pages/Info.tsx:29"}, "properties": {"repobilityId": "824a7a6c8b45e6fa", "scanner": "scanner-primary", "fingerprint": "e16d2bc412d091ed", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "compose/keycloak/theme/src/login/pages/Info.tsx"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-ab36cd9ec774de0f", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in frontend/__tests__/ai/execution-gate-card.test.tsx:1"}, "properties": {"repobilityId": "c48ae4f04225ef64", "scanner": "scanner-primary", "fingerprint": "ab36cd9ec774de0f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/__tests__/ai/execution-gate-card.test.tsx"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-9259fec4a6d913d7", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/components/auth/mock-login-form.tsx:48"}, "properties": {"repobilityId": "db2ff0179a049e05", "scanner": "scanner-primary", "fingerprint": "9259fec4a6d913d7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/components/auth/mock-login-form.tsx"}, "region": {"startLine": 48}}}]}, {"ruleId": "scanner-0d71d438cd6ade35", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in frontend/app/portal/(authenticated)/proposals/[id]/page.tsx:315"}, "properties": {"repobilityId": "64398aff8fd686ae", "scanner": "scanner-primary", "fingerprint": "0d71d438cd6ade35", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/app/portal/(authenticated)/proposals/[id]/page.tsx"}, "region": {"startLine": 315}}}]}, {"ruleId": "scanner-aa7a4c09127857ee", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in frontend/lib/auth/client/hooks.ts:88"}, "properties": {"repobilityId": "8c88e0e9fd633820", "scanner": "scanner-primary", "fingerprint": "aa7a4c09127857ee", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/lib/auth/client/hooks.ts"}, "region": {"startLine": 88}}}]}, {"ruleId": "scanner-190e3a0306aa3f5c", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in portal/app/(authenticated)/proposals/[id]/page.tsx:278"}, "properties": {"repobilityId": "f709398729c21e8c", "scanner": "scanner-primary", "fingerprint": "190e3a0306aa3f5c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "portal/app/(authenticated)/proposals/[id]/page.tsx"}, "region": {"startLine": 278}}}]}, {"ruleId": "scanner-f8920479ce13ff70", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in portal/e2e/helpers/auth.ts:79"}, "properties": {"repobilityId": "96673ac9aa8286ce", "scanner": "scanner-primary", "fingerprint": "f8920479ce13ff70", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "portal/e2e/helpers/auth.ts"}, "region": {"startLine": 79}}}]}, {"ruleId": "scanner-36514a6b17e1d602", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in tools/claude-slack-bot/src/claudeRunner.ts:1"}, "properties": {"repobilityId": "74a81c1a9e7e0850", "scanner": "scanner-primary", "fingerprint": "36514a6b17e1d602", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "tools/claude-slack-bot/src/claudeRunner.ts"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-35565ec7d80e5e78", "level": "error", "message": {"text": "Possible secret in backend/src/test/java/io/b2mash/b2b/b2bstrawman/integration/IntegrationControllerTest.java"}, "properties": {"repobilityId": "ee141a8b6723afe1", "scanner": "scanner-primary", "fingerprint": "35565ec7d80e5e78", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/src/test/java/io/b2mash/b2b/b2bstrawman/integration/IntegrationControllerTest.java"}, "region": {"startLine": 48}}}]}, {"ruleId": "scanner-6634c4990e71e5d6", "level": "warning", "message": {"text": "Insecure pattern 'weak_hash' in backend/src/main/java/io/b2mash/b2b/b2bstrawman/billing/SubscriptionItnService.java:306"}, "properties": {"repobilityId": "6adb5f73f9f0eaaf", "scanner": "scanner-primary", "fingerprint": "6634c4990e71e5d6", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "weak_hash"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/src/main/java/io/b2mash/b2b/b2bstrawman/billing/SubscriptionItnService.java"}, "region": {"startLine": 306}}}]}, {"ruleId": "scanner-e55290efa28e19c7", "level": "error", "message": {"text": "Possible secret in backend/src/main/java/io/b2mash/b2b/b2bstrawman/accessrequest/AccessRequestApprovalService.java"}, "properties": {"repobilityId": "f83bb7798351931a", "scanner": "scanner-primary", "fingerprint": "e55290efa28e19c7", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "backend/src/main/java/io/b2mash/b2b/b2bstrawman/accessrequest/AccessRequestApprovalService.java"}, "region": {"startLine": 36}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "877bbce6eb7dd90e", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 73}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "877bbce6eb7dd90e", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 110}}}]}, {"ruleId": "scanner-645e19ad7523a311", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "877bbce6eb7dd90e", "scanner": "scanner-primary", "fingerprint": "645e19ad7523a311", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 148}}}]}, {"ruleId": "scanner-c0d7e7ed5be2029c", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "587d0ab25bd2e3fd", "scanner": "scanner-primary", "fingerprint": "c0d7e7ed5be2029c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-prod.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b84c425e625a51e0", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "4b69506acab66522", "scanner": "scanner-primary", "fingerprint": "b84c425e625a51e0", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/qodana_code_quality.yml"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-58220d7bfe0e9201", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "c35c32fd93652005", "scanner": "scanner-primary", "fingerprint": "58220d7bfe0e9201", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/qodana_code_quality.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1e355a8e6b2c4da8", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "0039735a38b2f3cd", "scanner": "scanner-primary", "fingerprint": "1e355a8e6b2c4da8", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/rollback.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9dd07856a78c2c8a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 82}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9dd07856a78c2c8a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 120}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9dd07856a78c2c8a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 153}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9dd07856a78c2c8a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 186}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9dd07856a78c2c8a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 222}}}]}, {"ruleId": "scanner-36fd3c86ff87e5ff", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9dd07856a78c2c8a", "scanner": "scanner-primary", "fingerprint": "36fd3c86ff87e5ff", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 258}}}]}, {"ruleId": "scanner-a629b120390fd551", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "ed62bce030a81a93", "scanner": "scanner-primary", "fingerprint": "a629b120390fd551", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy-staging.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2ede05f035b21f09", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "15f6024d06673280", "scanner": "scanner-primary", "fingerprint": "2ede05f035b21f09", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/seed-images.yml"}, "region": {"startLine": 91}}}]}, {"ruleId": "scanner-829b84e1a24994eb", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "d5227043077b704a", "scanner": "scanner-primary", "fingerprint": "829b84e1a24994eb", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/seed-images.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e53e9728a55338d8", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "c67826ecc6a57cbc", "scanner": "scanner-primary", "fingerprint": "e53e9728a55338d8", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/terraform.yml"}, "region": {"startLine": 68}}}]}, {"ruleId": "scanner-4466f36e7138c73e", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "42c0482c98ff37ef", "scanner": "scanner-primary", "fingerprint": "4466f36e7138c73e", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/terraform.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-64192a3c67110d01", "level": "warning", "message": {"text": "GitHub Actions workflow grants broad write permissions"}, "properties": {"repobilityId": "87338a8bfcb6f435", "scanner": "scanner-primary", "fingerprint": "64192a3c67110d01", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "least-privilege"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5051f4fef5ed56f6", "level": "note", "message": {"text": "Very large file: compose/seed/lifecycle-test.sh (1363 lines)"}, "properties": {"repobilityId": "3075474e6a4a479e", "scanner": "scanner-primary", "fingerprint": "5051f4fef5ed56f6", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-1323cf4b2203bdc0", "level": "note", "message": {"text": "Very large file: backend/src/test/java/io/b2mash/b2b/b2bstrawman/verticals/legal/trustaccounting/transaction/TrustTransactionServiceTest.java (2854 lines)"}, "properties": {"repobilityId": "92dc5ebf3b0afe12", "scanner": "scanner-primary", "fingerprint": "1323cf4b2203bdc0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-788dc785174012bd", "level": "note", "message": {"text": "Very large file: backend/src/test/java/io/b2mash/b2b/b2bstrawman/verticals/legal/statement/StatementOfAccountContextBuilderTest.java (1257 lines)"}, "properties": {"repobilityId": "49ad16e075d39074", "scanner": "scanner-primary", "fingerprint": "788dc785174012bd", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-f1abe885de95d90a", "level": "note", "message": {"text": "Very large file: backend/src/main/java/io/b2mash/b2b/b2bstrawman/verticals/legal/trustaccounting/transaction/TrustTransactionService.java (1411 lines)"}, "properties": {"repobilityId": "9c5de58f56b6c0a9", "scanner": "scanner-primary", "fingerprint": "f1abe885de95d90a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b0b1d4079e3ea3ab", "level": "note", "message": {"text": "38 TODO/FIXME markers"}, "properties": {"repobilityId": "4b38c118003e07d2", "scanner": "scanner-primary", "fingerprint": "b0b1d4079e3ea3ab", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["maintenance"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "c09b555c9a3f4b01", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-0e8a76eb13fd3249", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: frontend/package.json"}, "properties": {"repobilityId": "d8c65da5b68ee95b", "scanner": "scanner-primary", "fingerprint": "0e8a76eb13fd3249", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b8fae141f052f3ab", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: docs/package.json"}, "properties": {"repobilityId": "e77ce50b08d152bb", "scanner": "scanner-primary", "fingerprint": "b8fae141f052f3ab", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-50218c90b43393bb", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/ui/package.json"}, "properties": {"repobilityId": "637e26a8c754e81d", "scanner": "scanner-primary", "fingerprint": "50218c90b43393bb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ui/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-b27b66da6f566f2e", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: portal/package.json"}, "properties": {"repobilityId": "7fe8dab19f18e243", "scanner": "scanner-primary", "fingerprint": "b27b66da6f566f2e", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "portal/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "7e163126740a03b2", "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": "730977f658303a4a", "scanner": "scanner-primary", "fingerprint": "72b2a6250083a784", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "incomplete", "generated-repo-pattern"]}}, {"ruleId": "scanner-2d0c7b7ab8f8aacf", "level": "warning", "message": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "properties": {"repobilityId": "830a142192ed51d6", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "82a460b8a2f62458", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "1a9237b5338d7f7f", "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": "f3dbfe81bb1c038b", "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": "7977f7106e58c60a", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-122f91b7f2906dc4", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/settings.json"}, "properties": {"repobilityId": "a2967269048b6a9d", "scanner": "scanner-primary", "fingerprint": "122f91b7f2906dc4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/settings.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-d3b9a9717c505941", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/template-extraction-ideation-2026-03-29.md"}, "properties": {"repobilityId": "1095bdaa8725b0ad", "scanner": "scanner-primary", "fingerprint": "d3b9a9717c505941", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/template-extraction-ideation-2026-03-29.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-11f60be1207ee6e7", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase62-ideation-2026-04-04.md"}, "properties": {"repobilityId": "0b6e1bfaeac78915", "scanner": "scanner-primary", "fingerprint": "11f60be1207ee6e7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase62-ideation-2026-04-04.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1aa88ae00efbf155", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase29-ideation-2026-02-27.md"}, "properties": {"repobilityId": "d650a13d3683178f", "scanner": "scanner-primary", "fingerprint": "1aa88ae00efbf155", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase29-ideation-2026-02-27.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-42a74ab3f3ca84ff", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase45-ideation-2026-03-12.md"}, "properties": {"repobilityId": "192434b0b9429ee3", "scanner": "scanner-primary", "fingerprint": "42a74ab3f3ca84ff", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase45-ideation-2026-03-12.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-c022b064aa1331a3", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase66-ideation-2026-04-17.md"}, "properties": {"repobilityId": "5e0b263cc8efd430", "scanner": "scanner-primary", "fingerprint": "c022b064aa1331a3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase66-ideation-2026-04-17.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-fe28812412665fed", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase44-ideation-2026-03-10.md"}, "properties": {"repobilityId": "09bb4d62f70e1181", "scanner": "scanner-primary", "fingerprint": "fe28812412665fed", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase44-ideation-2026-03-10.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e5010b862a4b0c1a", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/branding-kazi-2026-03-22.md"}, "properties": {"repobilityId": "6a4fabc8faf55d2c", "scanner": "scanner-primary", "fingerprint": "e5010b862a4b0c1a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/branding-kazi-2026-03-22.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-8b4735d35169f3ba", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase68-ideation-2026-04-18.md"}, "properties": {"repobilityId": "8edd592ad235aa20", "scanner": "scanner-primary", "fingerprint": "8b4735d35169f3ba", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase68-ideation-2026-04-18.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3f36a5cb116e795d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase75-ideation-2026-05-27.md"}, "properties": {"repobilityId": "7c74669dd1a496fc", "scanner": "scanner-primary", "fingerprint": "3f36a5cb116e795d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase75-ideation-2026-05-27.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-197a9d18bf0644c0", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/ideas/phase18-ideation-2026-02-20.md"}, "properties": {"repobilityId": "6699ded6ea672d95", "scanner": "scanner-primary", "fingerprint": "197a9d18bf0644c0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/ideas/phase18-ideation-2026-02-20.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-2f4db7418d2ef764", "level": "error", "message": {"text": "Agent instruction/config may expose a secret: infra/CLAUDE.md"}, "properties": {"repobilityId": "f53acc10f906b639", "scanner": "scanner-primary", "fingerprint": "2f4db7418d2ef764", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["agent-instructions", "secrets", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "infra/CLAUDE.md"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-002a2c7843a51d57", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: infra/CLAUDE.md"}, "properties": {"repobilityId": "6ec07ee681722b61", "scanner": "scanner-primary", "fingerprint": "002a2c7843a51d57", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "infra/CLAUDE.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e725d2ab884fbd49", "level": "note", "message": {"text": "Multiple root agent instruction files without precedence"}, "properties": {"repobilityId": "1953db6c89508d22", "scanner": "scanner-primary", "fingerprint": "e725d2ab884fbd49", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["agent-instructions", "governance"]}}, {"ruleId": "scanner-fc4789b6eb029d9a", "level": "none", "message": {"text": "Commented-code block (5 lines) in compose/keycloak/theme/src/login/pages/Register.tsx:17"}, "properties": {"repobilityId": "e9e363717ed6e097", "scanner": "scanner-primary", "fingerprint": "fc4789b6eb029d9a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a3acac899be983cd", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/__tests__/trust-coexistence.test.tsx:193"}, "properties": {"repobilityId": "edfae04fae4038e0", "scanner": "scanner-primary", "fingerprint": "a3acac899be983cd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ed8b714eaa2a7fae", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/__tests__/ai/execution-gate-card.test.tsx:28"}, "properties": {"repobilityId": "159a6f1889f4406e", "scanner": "scanner-primary", "fingerprint": "ed8b714eaa2a7fae", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3cc330f82092cf57", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/__tests__/field-definitions/CustomFieldSection.test.tsx:447"}, "properties": {"repobilityId": "142f696b86b4dd7b", "scanner": "scanner-primary", "fingerprint": "3cc330f82092cf57", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d070f5f65449af26", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/__tests__/components/dialog-family-ssr.snapshot.test.tsx:60"}, "properties": {"repobilityId": "6b0ee862db0ddc3c", "scanner": "scanner-primary", "fingerprint": "d070f5f65449af26", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-29c1aeed351c696e", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/__tests__/eslint-rules/no-aschild-adjacency.test.ts:195"}, "properties": {"repobilityId": "ffca0ebd6771ca6e", "scanner": "scanner-primary", "fingerprint": "29c1aeed351c696e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-393cda710d5a23c0", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/components/sidebar-user-footer.tsx:74"}, "properties": {"repobilityId": "e3f6cddf704a44ff", "scanner": "scanner-primary", "fingerprint": "393cda710d5a23c0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d8f17c6389373078", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/components/legal/matter-closure-dialog.tsx:91"}, "properties": {"repobilityId": "7d9b3fdcb2a94977", "scanner": "scanner-primary", "fingerprint": "d8f17c6389373078", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ffef40aaf533b794", "level": "none", "message": {"text": "Commented-code block (8 lines) in frontend/components/ai/execution-gate-card.tsx:72"}, "properties": {"repobilityId": "1eff8240154c30e4", "scanner": "scanner-primary", "fingerprint": "ffef40aaf533b794", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1210087865daacfc", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/components/activity/activity-feed-client.tsx:37"}, "properties": {"repobilityId": "d1d75df83942488e", "scanner": "scanner-primary", "fingerprint": "1210087865daacfc", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-83449fd3dd6c91a8", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/components/dashboard/sensitive-events-widget.tsx:71"}, "properties": {"repobilityId": "2a0a2fd9d55433d7", "scanner": "scanner-primary", "fingerprint": "83449fd3dd6c91a8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2cd41fff33c3b6da", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/components/proposals/__tests__/create-proposal-dialog.test.tsx:152"}, "properties": {"repobilityId": "9b8aa501c6075245", "scanner": "scanner-primary", "fingerprint": "2cd41fff33c3b6da", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-71a47adba3d5b0d2", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/components/customers/intake-fields-section.tsx:55"}, "properties": {"repobilityId": "62c5722c07855560", "scanner": "scanner-primary", "fingerprint": "71a47adba3d5b0d2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-84011874eebd4be4", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/components/customers/edit-customer-dialog.tsx:164"}, "properties": {"repobilityId": "5c92745a3023beff", "scanner": "scanner-primary", "fingerprint": "84011874eebd4be4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d324de7d81eb208e", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/components/customers/create-customer-dialog.tsx:190"}, "properties": {"repobilityId": "c12240de091c882f", "scanner": "scanner-primary", "fingerprint": "d324de7d81eb208e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6d0984a6217daea6", "level": "none", "message": {"text": "Commented-code block (9 lines) in frontend/components/billing-runs/cherry-pick-step.tsx:157"}, "properties": {"repobilityId": "90933351baaa703f", "scanner": "scanner-primary", "fingerprint": "6d0984a6217daea6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5a1bdeebd0d2ea03", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/components/assistant/specialist-panel.tsx:144"}, "properties": {"repobilityId": "da85a2a32cefd72b", "scanner": "scanner-primary", "fingerprint": "5a1bdeebd0d2ea03", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-eebe1d4e331a8ad9", "level": "note", "message": {"text": "Legacy-named symbol `isLegacy` in frontend/components/clauses/clauses-content.tsx:288"}, "properties": {"repobilityId": "3667e8b9d092c37f", "scanner": "scanner-primary", "fingerprint": "eebe1d4e331a8ad9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-cdf41190db14ec7b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/app/api/customers/route.ts:40"}, "properties": {"repobilityId": "c224753c8426c770", "scanner": "scanner-primary", "fingerprint": "cdf41190db14ec7b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-768319ce73bf5f61", "level": "none", "message": {"text": "Commented-code block (8 lines) in frontend/app/(app)/org/[slug]/settings/audit-log/audit-log-client.tsx:292"}, "properties": {"repobilityId": "e06f798c1c0640f5", "scanner": "scanner-primary", "fingerprint": "768319ce73bf5f61", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1ac4d3b222c642ce", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/projects/[id]/page.tsx:221"}, "properties": {"repobilityId": "46ded7d6a089600e", "scanner": "scanner-primary", "fingerprint": "1ac4d3b222c642ce", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5e27c49ad710e03d", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/projects/[id]/(tabs)/statements.tsx:1"}, "properties": {"repobilityId": "a424f0016b5ef9a6", "scanner": "scanner-primary", "fingerprint": "5e27c49ad710e03d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a201674973511c44", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/projects/[id]/(tabs)/disbursements.tsx:1"}, "properties": {"repobilityId": "9910b11b648cd657", "scanner": "scanner-primary", "fingerprint": "a201674973511c44", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5084359d79ec16ff", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/dashboard/page.tsx:106"}, "properties": {"repobilityId": "cc0f7d01c8e7e68f", "scanner": "scanner-primary", "fingerprint": "5084359d79ec16ff", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2c79a0834ecd14cb", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/app/(app)/org/[slug]/trust-accounting/client-ledgers/[customerId]/page.tsx:176"}, "properties": {"repobilityId": "484ef918e55c5c0f", "scanner": "scanner-primary", "fingerprint": "2c79a0834ecd14cb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1e023ad8123cfabf", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/app/(app)/org/[slug]/conflict-check/actions.ts:100"}, "properties": {"repobilityId": "10760fd3a1e72f6a", "scanner": "scanner-primary", "fingerprint": "1e023ad8123cfabf", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dc22092596fb4908", "level": "none", "message": {"text": "Commented-code block (6 lines) in frontend/app/accept-invite/complete/page.tsx:14"}, "properties": {"repobilityId": "00b384aefd01480f", "scanner": "scanner-primary", "fingerprint": "dc22092596fb4908", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-08b27fb6caa67254", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/lib/format.test.ts:33"}, "properties": {"repobilityId": "1e7a6245f3ce8b48", "scanner": "scanner-primary", "fingerprint": "08b27fb6caa67254", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e022bdad6c97db43", "level": "none", "message": {"text": "Commented-code block (10 lines) in frontend/lib/format.ts:8"}, "properties": {"repobilityId": "00cc17bc2336cbd2", "scanner": "scanner-primary", "fingerprint": "e022bdad6c97db43", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f2352722a04d74d3", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/lib/intl-polyfill.ts:11"}, "properties": {"repobilityId": "d2d0d299778dc7de", "scanner": "scanner-primary", "fingerprint": "f2352722a04d74d3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7d9b9c05e9c7d422", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/lib/auth/middleware.ts:74"}, "properties": {"repobilityId": "612a1fe4a35baf21", "scanner": "scanner-primary", "fingerprint": "7d9b9c05e9c7d422", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bb189fcc3ba39826", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/auth/client/hooks.ts:52"}, "properties": {"repobilityId": "538e5c52ab481e64", "scanner": "scanner-primary", "fingerprint": "bb189fcc3ba39826", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9ff88290484a12cf", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/api/assistant-specialists.ts:147"}, "properties": {"repobilityId": "ffd4189db88bbef0", "scanner": "scanner-primary", "fingerprint": "9ff88290484a12cf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-cddb5d52c815682f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/lib/api/portal-acceptance.ts:28"}, "properties": {"repobilityId": "98581c9a90f74010", "scanner": "scanner-primary", "fingerprint": "cddb5d52c815682f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d9519f283a8343cd", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/lib/schemas/ai-profile.ts:11"}, "properties": {"repobilityId": "902acf550d2bd6d3", "scanner": "scanner-primary", "fingerprint": "d9519f283a8343cd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0d7b9ba4c5a6a2a9", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/eslint-rules/no-aschild-adjacency.mjs:81"}, "properties": {"repobilityId": "04bc1a3b3908aa61", "scanner": "scanner-primary", "fingerprint": "0d7b9ba4c5a6a2a9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ca7e713835f1ded9", "level": "none", "message": {"text": "Commented-code block (5 lines) in frontend/e2e/tests/lifecycle-portal.spec.ts:123"}, "properties": {"repobilityId": "aca393dc87d63c23", "scanner": "scanner-primary", "fingerprint": "ca7e713835f1ded9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4bf856757c878f23", "level": "none", "message": {"text": "Commented-code block (7 lines) in frontend/e2e/tests/audit-log/audit-log-smoke.spec.ts:39"}, "properties": {"repobilityId": "6f4e6590dca2831f", "scanner": "scanner-primary", "fingerprint": "4bf856757c878f23", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0292b74a94afe75d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 frontend/e2e/helpers/mailpit.ts:31"}, "properties": {"repobilityId": "d684c4b72957a209", "scanner": "scanner-primary", "fingerprint": "0292b74a94afe75d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-bdf31024b3d4b3b8", "level": "none", "message": {"text": "Commented-code block (5 lines) in portal/app/(authenticated)/layout.tsx:30"}, "properties": {"repobilityId": "f7d30059516a86a8", "scanner": "scanner-primary", "fingerprint": "bdf31024b3d4b3b8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9d14200ebd5ef9af", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 portal/app/(authenticated)/requests/[id]/page.tsx:146"}, "properties": {"repobilityId": "0e8a974973fc565e", "scanner": "scanner-primary", "fingerprint": "9d14200ebd5ef9af", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c61c9dd83b7b85d2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 portal/lib/api-client.ts:24"}, "properties": {"repobilityId": "110fe573ca80bc08", "scanner": "scanner-primary", "fingerprint": "c61c9dd83b7b85d2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fcb53d1fa9b62a6f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 portal/e2e/helpers/auth.ts:42"}, "properties": {"repobilityId": "4b61b53318267f36", "scanner": "scanner-primary", "fingerprint": "fcb53d1fa9b62a6f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2d6ffa20a9f1093b", "level": "note", "message": {"text": "24 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "880bbf29bf1f87e1", "scanner": "scanner-primary", "fingerprint": "2d6ffa20a9f1093b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-0ba36a1996fe8b89", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:8025/api/v1/messages?limit=20 (frontend/e2e/tests/debug-kc-invite.spec.ts:15)"}, "properties": {"repobilityId": "3f021c18412fb760", "scanner": "scanner-primary", "fingerprint": "0ba36a1996fe8b89", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-358815753e8867f1", "level": "note", "message": {"text": "Unused endpoint: POST /token"}, "properties": {"repobilityId": "e9f0b7ce37fa46eb", "scanner": "scanner-primary", "fingerprint": "358815753e8867f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6d2796cd3a798a38", "level": "note", "message": {"text": "Unused endpoint: GET /userinfo/:userId"}, "properties": {"repobilityId": "23db290f8f2df556", "scanner": "scanner-primary", "fingerprint": "6d2796cd3a798a38", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-e4baedd96af08af8", "level": "note", "message": {"text": "Unused endpoint: GET /api/customers"}, "properties": {"repobilityId": "9e89ef69a4d89d2d", "scanner": "scanner-primary", "fingerprint": "e4baedd96af08af8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76eff11be61f4d88", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/tax"}, "properties": {"repobilityId": "3aa3e6dcfa3a2faf", "scanner": "scanner-primary", "fingerprint": "76eff11be61f4d88", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7ac24a7e5b911b52", "level": "note", "message": {"text": "Unused endpoint: POST /api/field-definitions"}, "properties": {"repobilityId": "676ab8ecd48de9f5", "scanner": "scanner-primary", "fingerprint": "7ac24a7e5b911b52", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-dd1e40cf89039288", "level": "note", "message": {"text": "Unused endpoint: POST /api/field-groups"}, "properties": {"repobilityId": "3f3165b29bac360c", "scanner": "scanner-primary", "fingerprint": "dd1e40cf89039288", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-71b1c31364b9649d", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/capacity"}, "properties": {"repobilityId": "2d8996879e265232", "scanner": "scanner-primary", "fingerprint": "71b1c31364b9649d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-ed0899d50d0562bd", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/time-reminders"}, "properties": {"repobilityId": "5a98f1762568729a", "scanner": "scanner-primary", "fingerprint": "ed0899d50d0562bd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2b56ef9335731725", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/expense"}, "properties": {"repobilityId": "48a451a16e37e8af", "scanner": "scanner-primary", "fingerprint": "2b56ef9335731725", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3dd370eeae28c923", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/compliance"}, "properties": {"repobilityId": "d2b64831e1bee3f3", "scanner": "scanner-primary", "fingerprint": "3dd370eeae28c923", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1280d33b4e27231c", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/request-reminders"}, "properties": {"repobilityId": "25c413cd5be520fe", "scanner": "scanner-primary", "fingerprint": "1280d33b4e27231c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-57682006b1eca788", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/acceptance"}, "properties": {"repobilityId": "ac8b71cb762d55d5", "scanner": "scanner-primary", "fingerprint": "57682006b1eca788", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-60bd9b54df98bfcb", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/portal-digest-cadence"}, "properties": {"repobilityId": "88cc053222d275d5", "scanner": "scanner-primary", "fingerprint": "60bd9b54df98bfcb", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3338eac1e1d0b54a", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/portal-retainer-member-display"}, "properties": {"repobilityId": "71146dbda19e7169", "scanner": "scanner-primary", "fingerprint": "3338eac1e1d0b54a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2bffc2596a61e55e", "level": "note", "message": {"text": "Unused endpoint: PUT /api/settings"}, "properties": {"repobilityId": "0f843597beeeaa9b", "scanner": "scanner-primary", "fingerprint": "2bffc2596a61e55e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5649620c4f5d8fd5", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/batch-billing"}, "properties": {"repobilityId": "79eb8903392a48ba", "scanner": "scanner-primary", "fingerprint": "5649620c4f5d8fd5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4b1a3bafba0cad37", "level": "note", "message": {"text": "Unused endpoint: PATCH /api/settings/data-protection"}, "properties": {"repobilityId": "78265498c901a020", "scanner": "scanner-primary", "fingerprint": "4b1a3bafba0cad37", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b7f4f733e8f8d79b", "level": "note", "message": {"text": "Unused endpoint: POST /api/tariff-schedules"}, "properties": {"repobilityId": "cfad02c41d542e94", "scanner": "scanner-primary", "fingerprint": "b7f4f733e8f8d79b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d4e00f2da0b7247d", "level": "note", "message": {"text": "Unused endpoint: POST /api/adverse-parties"}, "properties": {"repobilityId": "544ae2b5bfea10f0", "scanner": "scanner-primary", "fingerprint": "d4e00f2da0b7247d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b581d162f3110245", "level": "note", "message": {"text": "Unused endpoint: POST /api/court-dates"}, "properties": {"repobilityId": "591d23deb8ae4e7d", "scanner": "scanner-primary", "fingerprint": "b581d162f3110245", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c5e2b78e3737e653", "level": "note", "message": {"text": "Unused endpoint: POST /api/prescription-trackers"}, "properties": {"repobilityId": "caa3bb84b1b105f4", "scanner": "scanner-primary", "fingerprint": "c5e2b78e3737e653", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-21ea290201446de7", "level": "note", "message": {"text": "Unused endpoint: POST /api/onboarding/dismiss"}, "properties": {"repobilityId": "e1f4c9648ab67fcd", "scanner": "scanner-primary", "fingerprint": "21ea290201446de7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b2b0f779852d3f04", "level": "note", "message": {"text": "Unused endpoint: POST /api/clauses"}, "properties": {"repobilityId": "c010f0ec38544ee0", "scanner": "scanner-primary", "fingerprint": "b2b0f779852d3f04", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-95cfb69015fb6517", "level": "note", "message": {"text": "Unused endpoint: PUT /api/notifications/read-all"}, "properties": {"repobilityId": "9ad549035cf466c5", "scanner": "scanner-primary", "fingerprint": "95cfb69015fb6517", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b3bc4a685cc0f734", "level": "note", "message": {"text": "Unused endpoint: PUT /api/settings/modules"}, "properties": {"repobilityId": "9ef005ba3255fd26", "scanner": "scanner-primary", "fingerprint": "b3bc4a685cc0f734", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}