{"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-54a6d197f3c0b4ae", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/ncm.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/ncm.js:1"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-722dda436e07d6b5", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_contacts.js:276", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_contacts.js:276"}, "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-7696335e5141041f", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/documentPrintBuilder.source.js:910", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/documentPrintBuilder.source.js:910"}, "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-739c24f3fc5b0808", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/initials.js:27", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/initials.js:27"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-02d74b5690df1f3c", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/common.js:536", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/common.js:536"}, "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-182d47c567e6ab8d", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_settings2.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_settings2.js:1"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-c46ad4e7e85cf993", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_items.js:307", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_items.js:307"}, "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-a831a1742cfcbdaf", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_purchase.js:320", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_purchase.js:320"}, "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-d954a7102a3f31d3", "name": "Stray `console.log` in TS/JS \u2014 panel/scripts/items.js:17", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/items.js: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-2816666810f6fc4a", "name": "Stray `console.log` in TS/JS \u2014 panel/cgi-bin/common.js:342", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 panel/cgi-bin/common.js:342"}, "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-e2c67e958b4086ed", "name": "Stray `console.log` in TS/JS \u2014 screens/scripts.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts.js:1"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-56348e9b30cb2a2d", "name": "Stray `console.log` in TS/JS \u2014 screens/scripts/cds.js:258", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts/cds.js:258"}, "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-0fe6577e2487f122", "name": "Stray `console.log` in TS/JS \u2014 screens/scripts/ncm-ws.js:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts/ncm-ws.js:71"}, "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-c40a03d5abf05084", "name": "Stray `console.log` in TS/JS \u2014 screens/scripts/kds.js:261", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts/kds.js:261"}, "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-1cfaa08f59861491", "name": "Stray `console.log` in TS/JS \u2014 app/scripts/ncm-ws.js:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/ncm-ws.js:71"}, "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-1e3ec8664eda9cfc", "name": "Stray `console.log` in TS/JS \u2014 app/scripts/confettiKit.min.js:1", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/confettiKit.min.js:1"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4b176cc04255237a", "name": "Stray `console.log` in TS/JS \u2014 app/scripts/sign-message.js:79", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/sign-message.js:79"}, "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-7a6d8cdf85682746", "name": "Stray `console.log` in TS/JS \u2014 app/scripts/enjoyhint.min.js:3", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/enjoyhint.min.js:3"}, "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-e7ce320635b3f421", "name": "TODO/FIXME marker in shipping code \u2014 app-next/components/layout/pos-auth-guard.tsx:36", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/components/layout/pos-auth-guard.tsx:36"}, "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-b0a65e6c28f71421", "name": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/cart-panel.tsx:256", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/cart-panel.tsx:256"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-548ea807410e737d", "name": "TODO/FIXME marker in shipping code \u2014 app-next/components/register/cart-panel.tsx:194", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/components/register/cart-panel.tsx:194"}, "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-dbaff92ac75cf62f", "name": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/product-search-dialog.tsx:179", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/product-search-dialog.tsx:179"}, "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-c1e6445e252ebdeb", "name": "TODO/FIXME marker in shipping code \u2014 app-next/components/register/pay-dialog.tsx:203", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/components/register/pay-dialog.tsx:203"}, "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-05e0232032ee1fc2", "name": "Stray `console.log` in TS/JS \u2014 app-next/components/register/pay-dialog.tsx:218", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app-next/components/register/pay-dialog.tsx:218"}, "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-f8e62824f664379a", "name": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/customer-dialog.tsx:195", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/customer-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-2918382433348b15", "name": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/forms/phone-input.tsx:162", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/forms/phone-input.tsx:162"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d97331f199871d8b", "name": "TODO/FIXME marker in shipping code \u2014 app-next/app/api/pos/bootstrap/route.ts:33", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/app/api/pos/bootstrap/route.ts:33"}, "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-d4b13ca785e66146", "name": "TODO/FIXME marker in shipping code \u2014 app-next/app/(pos)/register/page.tsx:27", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/app/(pos)/register/page.tsx:27"}, "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-0280e3ec1b6f528b", "name": "TODO/FIXME marker in shipping code \u2014 app-next/lib/commands/create-customer.ts:56", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/commands/create-customer.ts:56"}, "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-5cc48b82133e8a8c", "name": "Stray `console.log` in TS/JS \u2014 app-next/lib/commands/create-sale.ts:242", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app-next/lib/commands/create-sale.ts:242"}, "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-56dab94b16a8766a", "name": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/qz-tray.ts:42", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/qz-tray.ts:42"}, "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-30d0d7b5c750422a", "name": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/barcode-scanner.ts:62", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/barcode-scanner.ts:62"}, "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-e8f9dc854b0f79ec", "name": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/ticket-builder.ts:46", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/ticket-builder.ts:46"}, "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-5f8f04481036a04e", "name": "TODO/FIXME marker in shipping code \u2014 app-next/lib/realtime/ncm-ws.ts:55", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/realtime/ncm-ws.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-4439c2a0e278a002", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/layout/app-sidebar.tsx:214", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/layout/app-sidebar.tsx:214"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6199186869449b05", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 panel-next/components/ui/chart.tsx:95", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 panel-next/components/ui/chart.tsx:95"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cac21fb9382a0668", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/admin/admin-sidebar.tsx:161", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/admin/admin-sidebar.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-071ace328e0bf661", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/items/categories-picker.tsx:138", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/items/categories-picker.tsx:138"}, "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-328056e1ca6c7d24", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/items/compounds-editor.tsx:276", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/items/compounds-editor.tsx:276"}, "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-58f78e004252cc0d", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/forms/phone-input.tsx:162", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/forms/phone-input.tsx:162"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b3f77c0680fdd251", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/page.tsx:302", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/page.tsx:302"}, "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-eb6fb34a52c25a4d", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/settings/team/page.tsx:160", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/settings/team/page.tsx:160"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-fa68556c372ce03c", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/settings/price-lists/[id]/page.tsx:104", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/settings/price-lists/[id]/page.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-d0f8ff5abeb35344", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/purchase/page.tsx:602", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/purchase/page.tsx:602"}, "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-ca4fbeec70ad4e63", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/items/[id]/page.tsx:1455", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/items/[id]/page.tsx:1455"}, "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-73630bfde4433a52", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/items/barcodes/page.tsx:292", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/items/barcodes/page.tsx:292"}, "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-051ccaa1df2ea85f", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/contacts/[id]/page.tsx:1001", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/contacts/[id]/page.tsx:1001"}, "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-db73efa65c469a60", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/page.tsx:125", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/page.tsx:125"}, "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-0e94058853f4e7d9", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/open-invoices/page.tsx:80", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/open-invoices/page.tsx:80"}, "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-e2b7389316caebda", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/transactions/page.tsx:91", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/transactions/page.tsx:91"}, "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-c634b97df34761ed", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/schedule/page.tsx:149", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/schedule/page.tsx:149"}, "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-e8d24b40da2e96ed", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/inventory/page.tsx:169", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/inventory/page.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-1349b9f54c78530c", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/giftcards/page.tsx:157", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/giftcards/page.tsx:157"}, "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-b2a17f671e2e5f8f", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/customers/page.tsx:68", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/customers/page.tsx:68"}, "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-d1261374a4140ce0", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/expenses/page.tsx:114", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/expenses/page.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-05c212bddb5dcbb6", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/summary/page.tsx:340", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/summary/page.tsx:340"}, "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-e50af7e913bd2a0c", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/products/page.tsx:62", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/products/page.tsx:62"}, "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-8d49a67eb016ee95", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/page.tsx:199", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/page.tsx:199"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ca4eb698714162c4", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/audit/page.tsx:42", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/audit/page.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-201f8f1d876f3ff3", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/companies/page.tsx:186", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/companies/page.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-9b35a01448d547a2", "name": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/companies/[id]/page.tsx:927", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/companies/[id]/page.tsx:927"}, "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-ff7e2337afbf6f2c", "name": "Stray `console.log` in TS/JS \u2014 ws-server/index.js:79", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 ws-server/index.js:79"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: 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-8987d6d1c30c7202", "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-593f89d6d7796a71", "name": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-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-d5a1cefd13bcd7ed", "name": "Dockerfile ADD downloads remote content without checksum", "shortDescription": {"text": "Dockerfile ADD downloads remote content without checksum"}, "fullDescription": {"text": "Remote build inputs can change or be replaced upstream. Use Dockerfile ADD --checksum or download with an explicit digest/signature verification step."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7e3f4f455aa60b3c", "name": "Dockerfile runs as root: panel/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: panel/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-7a21443178f04a95", "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-13beb4cfc06a6115", "name": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-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-a1da9a2a35f4ac2e", "name": "Dockerfile runs as root: api/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: api/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-45a8a5c4e41c8b2b", "name": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-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-ba342dc3d59c4de7", "name": "Dockerfile runs as root: app/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: app/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-1e8b59e1b5454cd3", "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-19b163d674dff1d3", "name": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-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-a224af17afb41d2e", "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-3ab72825f8e31180", "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-f314160d6abcfbcd", "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-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-30d7f74fd3581c9c", "name": "Insecure pattern 'direct_innerhtml_assignment' in panel/scripts/a_settings.js:143", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/scripts/a_settings.js:143"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-7c8b15276ea25147", "name": "Insecure pattern 'direct_innerhtml_assignment' in panel/scripts/initials.js:7", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/scripts/initials.js:7"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2a69f82e626eb562", "name": "Insecure pattern 'direct_innerhtml_assignment' in panel/admin/scripts/users.js:55", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/admin/scripts/users.js:55"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3826b59ad7cb0735", "name": "Insecure pattern 'direct_innerhtml_assignment' in panel/admin/scripts/companies.js:81", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/admin/scripts/companies.js:81"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8b3517035e482b8e", "name": "Insecure pattern 'direct_innerhtml_assignment' in screens/scripts/kds.js:408", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in screens/scripts/kds.js:408"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d3e7da95b66eac16", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/scripts/confettiKit.min.js:1", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/scripts/confettiKit.min.js:1"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1e34ef8322965417", "name": "Possible secret in app/scripts/sign-message.js", "shortDescription": {"text": "Possible secret in app/scripts/sign-message.js"}, "fullDescription": {"text": "Detected pattern matching private_key. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-d7f1c4a40e57cf72", "name": "Insecure pattern 'private_key_in_repo' in app/scripts/sign-message.js:41", "shortDescription": {"text": "Insecure pattern 'private_key_in_repo' in app/scripts/sign-message.js:41"}, "fullDescription": {"text": "Found a known-risky pattern (private_key_in_repo). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-5e3d57374a959d18", "name": "Insecure pattern 'direct_innerhtml_assignment' in app/scripts/enjoyhint.min.js:2", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/scripts/enjoyhint.min.js:2"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a4d1683d2507f017", "name": "Insecure pattern 'dangerous_innerhtml' in panel-next/components/ui/chart.tsx:95", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in panel-next/components/ui/chart.tsx:95"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-27924aa79fa4a517", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "shivammathur/setup-php@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-2901abac05ac78ac", "name": "Very large file: panel/scripts/common.js (6202 lines)", "shortDescription": {"text": "Very large file: panel/scripts/common.js (6202 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-2083d312e4c1a878", "name": "Very large file: panel/cgi-bin/common.js (4271 lines)", "shortDescription": {"text": "Very large file: panel/cgi-bin/common.js (4271 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-2b075fde1a9f1368", "name": "Very large file: panel-next/app/(panel)/items/[id]/page.tsx (1738 lines)", "shortDescription": {"text": "Very large file: panel-next/app/(panel)/items/[id]/page.tsx (1738 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-060d742a23641893", "name": "Very large file: panel-next/app/(panel)/contacts/[id]/page.tsx (1671 lines)", "shortDescription": {"text": "Very large file: panel-next/app/(panel)/contacts/[id]/page.tsx (1671 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 306 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-09139f0da0f0bf07", "name": "86 TODO/FIXME markers", "shortDescription": {"text": "86 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-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 177 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 560 placeholder/mock markers across 114 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-11825279136b53a3", "name": "CI is configured but no tests are detected", "shortDescription": {"text": "CI is configured but no tests are detected"}, "fullDescription": {"text": "A CI pipeline exists, but the scan found no test files to gate. Opus labeled this generated-code pattern as config theater: release machinery exists, but it has little behavioral signal."}, "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, tests. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "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, tests. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-2c5f98b152cddb6d", "name": "Agent authority lacks a verifier contract: .claude/launch.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/launch.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-5c57430bbab4ee58", "name": "Agent authority lacks a verifier contract: .claude/agents/context-updater.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/agents/context-updater.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-4354d75702005889", "name": "Legacy-named symbol `customersOld` in panel/scripts/a_report_dashboard.js:39", "shortDescription": {"text": "Legacy-named symbol `customersOld` in panel/scripts/a_report_dashboard.js:39"}, "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-aee783b2db81dfd9", "name": "Commented-code block (6 lines) in panel/scripts/a_report_dashboard.js:422", "shortDescription": {"text": "Commented-code block (6 lines) in panel/scripts/a_report_dashboard.js:422"}, "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-5261d1a790e66b31", "name": "Legacy-named symbol `maskDigitPosMapOld` in panel/scripts/initials.js:27", "shortDescription": {"text": "Legacy-named symbol `maskDigitPosMapOld` in panel/scripts/initials.js:27"}, "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-3c5efcdebe056444", "name": "Legacy-named symbol `content_copy` in panel/scripts/a_settings_templates.js:307", "shortDescription": {"text": "Legacy-named symbol `content_copy` in panel/scripts/a_settings_templates.js:307"}, "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-38b088a028359231", "name": "Commented-code block (16 lines) in panel/scripts/common.js:1144", "shortDescription": {"text": "Commented-code block (16 lines) in panel/scripts/common.js:1144"}, "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-8fad21d2c53d863b", "name": "Legacy-named symbol `content_copy` in panel/scripts/a_settings2.js:1", "shortDescription": {"text": "Legacy-named symbol `content_copy` in panel/scripts/a_settings2.js:1"}, "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-75bf1e2cc8f29f72", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/api/items.js:4", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/api/items.js:4"}, "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-59d3818e877774ab", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/api/contacts.js:4", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/api/contacts.js:4"}, "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-72e98d24b16bbdd1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/items/form.js:22", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/items/form.js:22"}, "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-ab74250b1037963e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/contacts/form.js:33", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/contacts/form.js:33"}, "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-b8eae3033e02fd28", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel/admin/scripts/users.js:47", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/admin/scripts/users.js:47"}, "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-2497b1f3825687bf", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel/admin/scripts/companies.js:58", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/admin/scripts/companies.js:58"}, "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-f02ab25ed6f96b7c", "name": "Commented-code block (16 lines) in panel/cgi-bin/common.js:565", "shortDescription": {"text": "Commented-code block (16 lines) in panel/cgi-bin/common.js:565"}, "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-c8ae0098f6b2dd0c", "name": "Legacy-named symbol `copyOld` in screens/scripts/cds.js:264", "shortDescription": {"text": "Legacy-named symbol `copyOld` in screens/scripts/cds.js:264"}, "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-11851e8d2b96a07c", "name": "Legacy-named symbol `copyOld` in screens/scripts/kds.js:267", "shortDescription": {"text": "Legacy-named symbol `copyOld` in screens/scripts/kds.js:267"}, "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-a61c0ee31a049d55", "name": "Commented-code block (8 lines) in app-next/components/ui/money-input.tsx:51", "shortDescription": {"text": "Commented-code block (8 lines) in app-next/components/ui/money-input.tsx:51"}, "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-58a53eae8f84f795", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app-next/lib/api-client.ts:62", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app-next/lib/api-client.ts:62"}, "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-392fe45eb5abc3b0", "name": "Commented-code block (5 lines) in panel-next/components/layout/panel-auth-guard.tsx:21", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/components/layout/panel-auth-guard.tsx:21"}, "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-f21acf8e3fed786c", "name": "Commented-code block (5 lines) in panel-next/components/layout/app-sidebar.tsx:261", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/components/layout/app-sidebar.tsx:261"}, "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-e04cd5a1451432d2", "name": "Commented-code block (8 lines) in panel-next/components/ui/money-input.tsx:52", "shortDescription": {"text": "Commented-code block (8 lines) in panel-next/components/ui/money-input.tsx:52"}, "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-e81abbeb2e2a3ac8", "name": "Commented-code block (5 lines) in panel-next/components/print-templates/canvas-block.tsx:161", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/components/print-templates/canvas-block.tsx:161"}, "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-ac9b816c1d7a8f48", "name": "Commented-code block (5 lines) in panel-next/app/api/admin/[...path]/route.ts:170", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/app/api/admin/[...path]/route.ts:170"}, "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-44c91bb9d8e91338", "name": "Commented-code block (5 lines) in panel-next/app/(panel)/page.tsx:102", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/app/(panel)/page.tsx:102"}, "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-c6d0966f3f51987f", "name": "Commented-code block (6 lines) in panel-next/app/(panel)/settings/page.tsx:245", "shortDescription": {"text": "Commented-code block (6 lines) in panel-next/app/(panel)/settings/page.tsx:245"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-340a6c62e8e48269", "name": "Commented-code block (6 lines) in panel-next/app/(panel)/reports/summary/page.tsx:61", "shortDescription": {"text": "Commented-code block (6 lines) in panel-next/app/(panel)/reports/summary/page.tsx:61"}, "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-4d6cdaa30a943627", "name": "Commented-code block (5 lines) in panel-next/app/(auth)/signup/page.tsx:83", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/app/(auth)/signup/page.tsx:83"}, "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-3acd3d92b3473a53", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/app/(auth)/signup/page.tsx:90", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/app/(auth)/signup/page.tsx:90"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1aa0fae2af49c3e8", "name": "Commented-code block (5 lines) in panel-next/lib/api-client.ts:53", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/lib/api-client.ts:53"}, "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-b442f038cd6fcbd8", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/lib/api-client.ts:83", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/lib/api-client.ts:83"}, "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-5e4b6b40bdbd32e3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/lib/api-admin.ts:44", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/lib/api-admin.ts:44"}, "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-b996c3fe63369de1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/hooks/use-dashboard-widget.ts:137", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/hooks/use-dashboard-widget.ts:137"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c840fed8e60f434d", "name": "Commented-code block (5 lines) in panel-next/hooks/use-contacts.ts:191", "shortDescription": {"text": "Commented-code block (5 lines) in panel-next/hooks/use-contacts.ts:191"}, "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-319e66a630e14977", "name": "2 env vars used in code but missing from .env.example", "shortDescription": {"text": "2 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `NEXT_PUBLIC_API_URL`, `REDIS_URL`. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-cbe6296fcbe9dde4", "name": "Dangling fetch: POST /bff/admin/login.php (panel/admin/scripts/login.js:21)", "shortDescription": {"text": "Dangling fetch: POST /bff/admin/login.php (panel/admin/scripts/login.js:21)"}, "fullDescription": {"text": "`panel/admin/scripts/login.js:21` calls `POST /bff/admin/login.php` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bff/admin/login.php`\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-462bf6e822d0b466", "name": "Dangling fetch: POST /bff/admin/logout.php (panel/admin/scripts/users.js:117)", "shortDescription": {"text": "Dangling fetch: POST /bff/admin/logout.php (panel/admin/scripts/users.js:117)"}, "fullDescription": {"text": "`panel/admin/scripts/users.js:117` calls `POST /bff/admin/logout.php` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bff/admin/logout.php`\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-355cb4dff5978cad", "name": "Dangling fetch: POST /bff/admin/companies.php?action=resolveRequest (panel/admin/scripts/companies.js:502)", "shortDescription": {"text": "Dangling fetch: POST /bff/admin/companies.php?action=resolveRequest (panel/admin/scripts/companies.js:502)"}, "fullDescription": {"text": "`panel/admin/scripts/companies.js:502` calls `POST /bff/admin/companies.php?action=resolveRequest` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bff/admin/companies.php`\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-8ce79731f3793fb5", "name": "Dangling fetch: POST /bff/admin/logout.php (panel/admin/scripts/companies.js:771)", "shortDescription": {"text": "Dangling fetch: POST /bff/admin/logout.php (panel/admin/scripts/companies.js:771)"}, "fullDescription": {"text": "`panel/admin/scripts/companies.js:771` calls `POST /bff/admin/logout.php` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/bff/admin/logout.php`\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-49302075ff4efeda", "name": "Dangling fetch: POST /api/admin/users.php (panel-next/hooks/use-admin.ts:385)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/users.php (panel-next/hooks/use-admin.ts:385)"}, "fullDescription": {"text": "`panel-next/hooks/use-admin.ts:385` calls `POST /api/admin/users.php` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users.php`\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-474a40573cf00033", "name": "Dangling fetch: GET /api/dashboard/income-chart?${params.toString()} (panel-next/hooks/use-dashboard-widget.ts:137)", "shortDescription": {"text": "Dangling fetch: GET /api/dashboard/income-chart?${params.toString()} (panel-next/hooks/use-dashboard-widget.ts:137)"}, "fullDescription": {"text": "`panel-next/hooks/use-dashboard-widget.ts:137` calls `GET /api/dashboard/income-chart?${params.toString()}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/dashboard/income-chart`\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-f284425a416887b3", "name": "Unused endpoint: POST /v1/contacts", "shortDescription": {"text": "Unused endpoint: POST /v1/contacts"}, "fullDescription": {"text": "`app-next/lib/commands/create-customer.ts` declares `POST /v1/contacts` 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-621911d708fc8af4", "name": "Unused endpoint: POST /login.php", "shortDescription": {"text": "Unused endpoint: POST /login.php"}, "fullDescription": {"text": "`panel-next/app/admin/login/page.tsx` declares `POST /login.php` 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-7c19afa1cffd0d4e", "name": "Unused endpoint: POST /v1/login", "shortDescription": {"text": "Unused endpoint: POST /v1/login"}, "fullDescription": {"text": "`panel-next/app/(auth)/login/page.tsx` declares `POST /v1/login` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a6c305793fd4945d", "name": "Unused endpoint: POST /v1/signup/start", "shortDescription": {"text": "Unused endpoint: POST /v1/signup/start"}, "fullDescription": {"text": "`panel-next/app/(auth)/signup/page.tsx` declares `POST /v1/signup/start` 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-41da9c4e93e4f746", "name": "Unused endpoint: POST /v1/signup/verify", "shortDescription": {"text": "Unused endpoint: POST /v1/signup/verify"}, "fullDescription": {"text": "`panel-next/app/(auth)/signup/page.tsx` declares `POST /v1/signup/verify` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-62ad4c8c63e50e6d", "name": "Unused endpoint: POST /v1/signup", "shortDescription": {"text": "Unused endpoint: POST /v1/signup"}, "fullDescription": {"text": "`panel-next/app/(auth)/signup/page.tsx` declares `POST /v1/signup` 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-50821ec1669b6f8a", "name": "Unused endpoint: GET /v1/brands", "shortDescription": {"text": "Unused endpoint: GET /v1/brands"}, "fullDescription": {"text": "`panel-next/hooks/use-brands.ts` declares `GET /v1/brands` 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-3be1d0dfb76d1de7", "name": "Unused endpoint: GET /v1/taxes", "shortDescription": {"text": "Unused endpoint: GET /v1/taxes"}, "fullDescription": {"text": "`panel-next/hooks/use-taxes.ts` declares `GET /v1/taxes` 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-4e44aad0ef34a79e", "name": "Unused endpoint: GET /v1/users?resource=roles", "shortDescription": {"text": "Unused endpoint: GET /v1/users?resource=roles"}, "fullDescription": {"text": "`panel-next/hooks/use-team.ts` declares `GET /v1/users?resource=roles` 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-7a899b0da3a4371d", "name": "Unused endpoint: GET /v1/categories", "shortDescription": {"text": "Unused endpoint: GET /v1/categories"}, "fullDescription": {"text": "`panel-next/hooks/use-categories.ts` declares `GET /v1/categories` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-99fc36db98c134ce", "name": "Unused endpoint: POST /logout", "shortDescription": {"text": "Unused endpoint: POST /logout"}, "fullDescription": {"text": "`panel-next/hooks/use-admin.ts` declares `POST /logout` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-70455b9324d77aff", "name": "Unused endpoint: GET /companies.php?plans=1", "shortDescription": {"text": "Unused endpoint: GET /companies.php?plans=1"}, "fullDescription": {"text": "`panel-next/hooks/use-admin.ts` declares `GET /companies.php?plans=1` 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-888615f4ba8fd7fd", "name": "Unused endpoint: POST /companies.php?action=resolveRequest", "shortDescription": {"text": "Unused endpoint: POST /companies.php?action=resolveRequest"}, "fullDescription": {"text": "`panel-next/hooks/use-admin.ts` declares `POST /companies.php?action=resolveRequest` 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-28a90364d1735211", "name": "Unused endpoint: GET /users.php", "shortDescription": {"text": "Unused endpoint: GET /users.php"}, "fullDescription": {"text": "`panel-next/hooks/use-admin.ts` declares `GET /users.php` 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-a1f5eddb14c6ff4a", "name": "Unused endpoint: POST /v1/items?resource=group", "shortDescription": {"text": "Unused endpoint: POST /v1/items?resource=group"}, "fullDescription": {"text": "`panel-next/hooks/use-items.ts` declares `POST /v1/items?resource=group` 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-fe66cb3d660c3885", "name": "Unused endpoint: POST /v1/items?resource=bulk-edit", "shortDescription": {"text": "Unused endpoint: POST /v1/items?resource=bulk-edit"}, "fullDescription": {"text": "`panel-next/hooks/use-items.ts` declares `POST /v1/items?resource=bulk-edit` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b0b5757fd94364e3", "name": "Unused endpoint: GET /v1/taxonomies", "shortDescription": {"text": "Unused endpoint: GET /v1/taxonomies"}, "fullDescription": {"text": "`panel-next/hooks/use-items.ts` declares `GET /v1/taxonomies` 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-1658c07109ac0cf8", "name": "Unused endpoint: GET /v1/currencies", "shortDescription": {"text": "Unused endpoint: GET /v1/currencies"}, "fullDescription": {"text": "`panel-next/hooks/use-items.ts` declares `GET /v1/currencies` 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-4bb41679a4d77c01", "name": "Unused endpoint: GET /v1/settings?view=currencies", "shortDescription": {"text": "Unused endpoint: GET /v1/settings?view=currencies"}, "fullDescription": {"text": "`panel-next/hooks/use-settings.ts` declares `GET /v1/settings?view=currencies` 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-b81539cd09c337f1", "name": "Unused endpoint: POST /v1/settings", "shortDescription": {"text": "Unused endpoint: POST /v1/settings"}, "fullDescription": {"text": "`panel-next/hooks/use-settings.ts` declares `POST /v1/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-f704d23a72d234b9", "name": "Unused endpoint: GET /v1/document-templates", "shortDescription": {"text": "Unused endpoint: GET /v1/document-templates"}, "fullDescription": {"text": "`panel-next/hooks/use-document-templates.ts` declares `GET /v1/document-templates` 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-d401e239f75668d0", "name": "Unused endpoint: POST /v1/customer_address", "shortDescription": {"text": "Unused endpoint: POST /v1/customer_address"}, "fullDescription": {"text": "`panel-next/hooks/use-contacts.ts` declares `POST /v1/customer_address` 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-6e2c5ce35996298f", "name": "Unused endpoint: POST /v1/modules", "shortDescription": {"text": "Unused endpoint: POST /v1/modules"}, "fullDescription": {"text": "`panel-next/hooks/use-modules.ts` declares `POST /v1/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/23072"}, "properties": {"repository": "xsmurphy/punto-legacy", "repoUrl": "https://github.com/xsmurphy/punto-legacy", "branch": "main"}, "results": [{"ruleId": "scanner-54a6d197f3c0b4ae", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/ncm.js:1"}, "properties": {"repobilityId": "ec9d88c1a0b0313d", "scanner": "scanner-primary", "fingerprint": "54a6d197f3c0b4ae", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-722dda436e07d6b5", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_contacts.js:276"}, "properties": {"repobilityId": "70716e4b4f9308d3", "scanner": "scanner-primary", "fingerprint": "722dda436e07d6b5", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7696335e5141041f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/documentPrintBuilder.source.js:910"}, "properties": {"repobilityId": "0ca89cd0320ec57b", "scanner": "scanner-primary", "fingerprint": "7696335e5141041f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-739c24f3fc5b0808", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/initials.js:27"}, "properties": {"repobilityId": "f719ad877ce131d5", "scanner": "scanner-primary", "fingerprint": "739c24f3fc5b0808", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-02d74b5690df1f3c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/common.js:536"}, "properties": {"repobilityId": "f10fbdc45c8c3e02", "scanner": "scanner-primary", "fingerprint": "02d74b5690df1f3c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-182d47c567e6ab8d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_settings2.js:1"}, "properties": {"repobilityId": "7481fb2e3e2ca1a6", "scanner": "scanner-primary", "fingerprint": "182d47c567e6ab8d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c46ad4e7e85cf993", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_items.js:307"}, "properties": {"repobilityId": "e986489dfc7d171e", "scanner": "scanner-primary", "fingerprint": "c46ad4e7e85cf993", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a831a1742cfcbdaf", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/a_purchase.js:320"}, "properties": {"repobilityId": "3bda4d5b35a0fc48", "scanner": "scanner-primary", "fingerprint": "a831a1742cfcbdaf", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d954a7102a3f31d3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/scripts/items.js:17"}, "properties": {"repobilityId": "f85722db8009c6e0", "scanner": "scanner-primary", "fingerprint": "d954a7102a3f31d3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2816666810f6fc4a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 panel/cgi-bin/common.js:342"}, "properties": {"repobilityId": "a52b4b2972e8b381", "scanner": "scanner-primary", "fingerprint": "2816666810f6fc4a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e2c67e958b4086ed", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts.js:1"}, "properties": {"repobilityId": "1f2270acfa5b5dcf", "scanner": "scanner-primary", "fingerprint": "e2c67e958b4086ed", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-56348e9b30cb2a2d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts/cds.js:258"}, "properties": {"repobilityId": "caff7a5a34113b51", "scanner": "scanner-primary", "fingerprint": "56348e9b30cb2a2d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0fe6577e2487f122", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts/ncm-ws.js:71"}, "properties": {"repobilityId": "18abfa3a697d012c", "scanner": "scanner-primary", "fingerprint": "0fe6577e2487f122", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-c40a03d5abf05084", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 screens/scripts/kds.js:261"}, "properties": {"repobilityId": "727c97c5827affce", "scanner": "scanner-primary", "fingerprint": "c40a03d5abf05084", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1cfaa08f59861491", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/ncm-ws.js:71"}, "properties": {"repobilityId": "e77ec534721dcaf9", "scanner": "scanner-primary", "fingerprint": "1cfaa08f59861491", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1e3ec8664eda9cfc", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/confettiKit.min.js:1"}, "properties": {"repobilityId": "ff2cd8a6da9f045a", "scanner": "scanner-primary", "fingerprint": "1e3ec8664eda9cfc", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4b176cc04255237a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/sign-message.js:79"}, "properties": {"repobilityId": "64ced3cb6494cdd0", "scanner": "scanner-primary", "fingerprint": "4b176cc04255237a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-7a6d8cdf85682746", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/scripts/enjoyhint.min.js:3"}, "properties": {"repobilityId": "c64cb81ea384bf60", "scanner": "scanner-primary", "fingerprint": "7a6d8cdf85682746", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-e7ce320635b3f421", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/components/layout/pos-auth-guard.tsx:36"}, "properties": {"repobilityId": "af451d62d6bc6f55", "scanner": "scanner-primary", "fingerprint": "e7ce320635b3f421", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-b0a65e6c28f71421", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/cart-panel.tsx:256"}, "properties": {"repobilityId": "4905a5a7ff75a929", "scanner": "scanner-primary", "fingerprint": "b0a65e6c28f71421", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-548ea807410e737d", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/components/register/cart-panel.tsx:194"}, "properties": {"repobilityId": "e2eeb49bcd3e951c", "scanner": "scanner-primary", "fingerprint": "548ea807410e737d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-dbaff92ac75cf62f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/product-search-dialog.tsx:179"}, "properties": {"repobilityId": "861f3ddde96e0535", "scanner": "scanner-primary", "fingerprint": "dbaff92ac75cf62f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c1e6445e252ebdeb", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/components/register/pay-dialog.tsx:203"}, "properties": {"repobilityId": "3807d0d6c496deb8", "scanner": "scanner-primary", "fingerprint": "c1e6445e252ebdeb", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-05e0232032ee1fc2", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app-next/components/register/pay-dialog.tsx:218"}, "properties": {"repobilityId": "9ba435e850d310f8", "scanner": "scanner-primary", "fingerprint": "05e0232032ee1fc2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f8e62824f664379a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/register/customer-dialog.tsx:195"}, "properties": {"repobilityId": "23081ce78550da2e", "scanner": "scanner-primary", "fingerprint": "f8e62824f664379a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2918382433348b15", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app-next/components/forms/phone-input.tsx:162"}, "properties": {"repobilityId": "ca784605feab95b9", "scanner": "scanner-primary", "fingerprint": "2918382433348b15", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d97331f199871d8b", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/app/api/pos/bootstrap/route.ts:33"}, "properties": {"repobilityId": "4f383866a8438681", "scanner": "scanner-primary", "fingerprint": "d97331f199871d8b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-d4b13ca785e66146", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/app/(pos)/register/page.tsx:27"}, "properties": {"repobilityId": "2c8d21e17ef64e4b", "scanner": "scanner-primary", "fingerprint": "d4b13ca785e66146", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-0280e3ec1b6f528b", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/commands/create-customer.ts:56"}, "properties": {"repobilityId": "6ed22942a3e2841d", "scanner": "scanner-primary", "fingerprint": "0280e3ec1b6f528b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-5cc48b82133e8a8c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app-next/lib/commands/create-sale.ts:242"}, "properties": {"repobilityId": "8a4fa2402bd631ad", "scanner": "scanner-primary", "fingerprint": "5cc48b82133e8a8c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-56dab94b16a8766a", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/qz-tray.ts:42"}, "properties": {"repobilityId": "208db4a7776bb566", "scanner": "scanner-primary", "fingerprint": "56dab94b16a8766a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-30d0d7b5c750422a", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/barcode-scanner.ts:62"}, "properties": {"repobilityId": "15ebbffe9eb0beb7", "scanner": "scanner-primary", "fingerprint": "30d0d7b5c750422a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-e8f9dc854b0f79ec", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/hardware/ticket-builder.ts:46"}, "properties": {"repobilityId": "59606c6574b7c32a", "scanner": "scanner-primary", "fingerprint": "e8f9dc854b0f79ec", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-5f8f04481036a04e", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 app-next/lib/realtime/ncm-ws.ts:55"}, "properties": {"repobilityId": "54e3f5cd9e16faa7", "scanner": "scanner-primary", "fingerprint": "5f8f04481036a04e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-4439c2a0e278a002", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/layout/app-sidebar.tsx:214"}, "properties": {"repobilityId": "6a5514203c3b272f", "scanner": "scanner-primary", "fingerprint": "4439c2a0e278a002", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6199186869449b05", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 panel-next/components/ui/chart.tsx:95"}, "properties": {"repobilityId": "a8141f899c7fac27", "scanner": "scanner-primary", "fingerprint": "6199186869449b05", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-cac21fb9382a0668", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/admin/admin-sidebar.tsx:161"}, "properties": {"repobilityId": "bc07b723110aa050", "scanner": "scanner-primary", "fingerprint": "cac21fb9382a0668", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-071ace328e0bf661", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/items/categories-picker.tsx:138"}, "properties": {"repobilityId": "c2f1cc9e4f947cfa", "scanner": "scanner-primary", "fingerprint": "071ace328e0bf661", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-328056e1ca6c7d24", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/items/compounds-editor.tsx:276"}, "properties": {"repobilityId": "d0984b0724af75ac", "scanner": "scanner-primary", "fingerprint": "328056e1ca6c7d24", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-58f78e004252cc0d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/components/forms/phone-input.tsx:162"}, "properties": {"repobilityId": "405ac4df908466be", "scanner": "scanner-primary", "fingerprint": "58f78e004252cc0d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b3f77c0680fdd251", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/page.tsx:302"}, "properties": {"repobilityId": "efd90f0b8b095855", "scanner": "scanner-primary", "fingerprint": "b3f77c0680fdd251", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eb6fb34a52c25a4d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/settings/team/page.tsx:160"}, "properties": {"repobilityId": "b34b465f08ab0a25", "scanner": "scanner-primary", "fingerprint": "eb6fb34a52c25a4d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa68556c372ce03c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/settings/price-lists/[id]/page.tsx:104"}, "properties": {"repobilityId": "e770c26d59707795", "scanner": "scanner-primary", "fingerprint": "fa68556c372ce03c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d0f8ff5abeb35344", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/purchase/page.tsx:602"}, "properties": {"repobilityId": "41d44353e1a6ec96", "scanner": "scanner-primary", "fingerprint": "d0f8ff5abeb35344", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca4fbeec70ad4e63", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/items/[id]/page.tsx:1455"}, "properties": {"repobilityId": "96d162a430a671c2", "scanner": "scanner-primary", "fingerprint": "ca4fbeec70ad4e63", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-73630bfde4433a52", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/items/barcodes/page.tsx:292"}, "properties": {"repobilityId": "d3da129aeb838b85", "scanner": "scanner-primary", "fingerprint": "73630bfde4433a52", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-051ccaa1df2ea85f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/contacts/[id]/page.tsx:1001"}, "properties": {"repobilityId": "bb23d1e3781c0364", "scanner": "scanner-primary", "fingerprint": "051ccaa1df2ea85f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-db73efa65c469a60", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/page.tsx:125"}, "properties": {"repobilityId": "ddc673653ab9844a", "scanner": "scanner-primary", "fingerprint": "db73efa65c469a60", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0e94058853f4e7d9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/open-invoices/page.tsx:80"}, "properties": {"repobilityId": "df749a3c34c79236", "scanner": "scanner-primary", "fingerprint": "0e94058853f4e7d9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e2b7389316caebda", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/transactions/page.tsx:91"}, "properties": {"repobilityId": "6063786fed79654f", "scanner": "scanner-primary", "fingerprint": "e2b7389316caebda", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c634b97df34761ed", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/schedule/page.tsx:149"}, "properties": {"repobilityId": "1bc5c4a4525a82d2", "scanner": "scanner-primary", "fingerprint": "c634b97df34761ed", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e8d24b40da2e96ed", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/inventory/page.tsx:169"}, "properties": {"repobilityId": "c88b97f10f079137", "scanner": "scanner-primary", "fingerprint": "e8d24b40da2e96ed", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1349b9f54c78530c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/giftcards/page.tsx:157"}, "properties": {"repobilityId": "f0e737f2a1acf6f6", "scanner": "scanner-primary", "fingerprint": "1349b9f54c78530c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b2a17f671e2e5f8f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/customers/page.tsx:68"}, "properties": {"repobilityId": "5ebbfc033c6b9c67", "scanner": "scanner-primary", "fingerprint": "b2a17f671e2e5f8f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d1261374a4140ce0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/expenses/page.tsx:114"}, "properties": {"repobilityId": "fbc2194ab9d25fdb", "scanner": "scanner-primary", "fingerprint": "d1261374a4140ce0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-05c212bddb5dcbb6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/summary/page.tsx:340"}, "properties": {"repobilityId": "b34cf5659945ca50", "scanner": "scanner-primary", "fingerprint": "05c212bddb5dcbb6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e50af7e913bd2a0c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(panel)/reports/products/page.tsx:62"}, "properties": {"repobilityId": "27d35f22987385be", "scanner": "scanner-primary", "fingerprint": "e50af7e913bd2a0c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8d49a67eb016ee95", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/page.tsx:199"}, "properties": {"repobilityId": "a82cbdab95dbc36c", "scanner": "scanner-primary", "fingerprint": "8d49a67eb016ee95", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca4eb698714162c4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/audit/page.tsx:42"}, "properties": {"repobilityId": "9567d805bee0a342", "scanner": "scanner-primary", "fingerprint": "ca4eb698714162c4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-201f8f1d876f3ff3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/companies/page.tsx:186"}, "properties": {"repobilityId": "a94cbf9ecbe6b1e2", "scanner": "scanner-primary", "fingerprint": "201f8f1d876f3ff3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9b35a01448d547a2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 panel-next/app/(admin)/admin/companies/[id]/page.tsx:927"}, "properties": {"repobilityId": "1552daf86290ed8a", "scanner": "scanner-primary", "fingerprint": "9b35a01448d547a2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ff7e2337afbf6f2c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 ws-server/index.js:79"}, "properties": {"repobilityId": "c5c2bf035ec4a1f9", "scanner": "scanner-primary", "fingerprint": "ff7e2337afbf6f2c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-8987d6d1c30c7202", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "a402807e61732d3e", "scanner": "scanner-primary", "fingerprint": "8987d6d1c30c7202", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-593f89d6d7796a71", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine"}, "properties": {"repobilityId": "0d1487f6a056320f", "scanner": "scanner-primary", "fingerprint": "593f89d6d7796a71", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 47}}}]}, {"ruleId": "scanner-d5a1cefd13bcd7ed", "level": "warning", "message": {"text": "Dockerfile ADD downloads remote content without checksum"}, "properties": {"repobilityId": "8e72ea2e5330d1f5", "scanner": "scanner-primary", "fingerprint": "d5a1cefd13bcd7ed", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "docker", "checksum"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 52}}}]}, {"ruleId": "scanner-7e3f4f455aa60b3c", "level": "warning", "message": {"text": "Dockerfile runs as root: panel/Dockerfile"}, "properties": {"repobilityId": "8345e5f7683e71a7", "scanner": "scanner-primary", "fingerprint": "7e3f4f455aa60b3c", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-7a21443178f04a95", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "c5282592b3dd72d9", "scanner": "scanner-primary", "fingerprint": "7a21443178f04a95", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel/Dockerfile"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-13beb4cfc06a6115", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine"}, "properties": {"repobilityId": "cc755d39aa07d9a8", "scanner": "scanner-primary", "fingerprint": "13beb4cfc06a6115", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel/Dockerfile"}, "region": {"startLine": 43}}}]}, {"ruleId": "scanner-a1da9a2a35f4ac2e", "level": "warning", "message": {"text": "Dockerfile runs as root: api/Dockerfile"}, "properties": {"repobilityId": "d158f2064abae541", "scanner": "scanner-primary", "fingerprint": "a1da9a2a35f4ac2e", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-45a8a5c4e41c8b2b", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine"}, "properties": {"repobilityId": "823fa4dcec3a9e03", "scanner": "scanner-primary", "fingerprint": "45a8a5c4e41c8b2b", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "api/Dockerfile"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-ba342dc3d59c4de7", "level": "warning", "message": {"text": "Dockerfile runs as root: app/Dockerfile"}, "properties": {"repobilityId": "99bdd9dec7b91e2f", "scanner": "scanner-primary", "fingerprint": "ba342dc3d59c4de7", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-1e8b59e1b5454cd3", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "b0bdea0d37b39202", "scanner": "scanner-primary", "fingerprint": "1e8b59e1b5454cd3", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/Dockerfile"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-19b163d674dff1d3", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: php:8.4-cli-alpine"}, "properties": {"repobilityId": "da9d4e108d13c3bf", "scanner": "scanner-primary", "fingerprint": "19b163d674dff1d3", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/Dockerfile"}, "region": {"startLine": 37}}}]}, {"ruleId": "scanner-a224af17afb41d2e", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "87bf2d9e32b6eeb2", "scanner": "scanner-primary", "fingerprint": "a224af17afb41d2e", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app-next/Dockerfile"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-a224af17afb41d2e", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "5fe2afa3dc043730", "scanner": "scanner-primary", "fingerprint": "a224af17afb41d2e", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app-next/Dockerfile"}, "region": {"startLine": 29}}}]}, {"ruleId": "scanner-a224af17afb41d2e", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "798ea80967eb8f1f", "scanner": "scanner-primary", "fingerprint": "a224af17afb41d2e", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app-next/Dockerfile"}, "region": {"startLine": 52}}}]}, {"ruleId": "scanner-3ab72825f8e31180", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "48c8c888da4bc1b2", "scanner": "scanner-primary", "fingerprint": "3ab72825f8e31180", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel-next/Dockerfile"}, "region": {"startLine": 14}}}]}, {"ruleId": "scanner-3ab72825f8e31180", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "f48ceaa6d91cf2bf", "scanner": "scanner-primary", "fingerprint": "3ab72825f8e31180", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel-next/Dockerfile"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-3ab72825f8e31180", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:22-alpine"}, "properties": {"repobilityId": "9848925d1c34f890", "scanner": "scanner-primary", "fingerprint": "3ab72825f8e31180", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel-next/Dockerfile"}, "region": {"startLine": 51}}}]}, {"ruleId": "scanner-f314160d6abcfbcd", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "a075cacd1780ed48", "scanner": "scanner-primary", "fingerprint": "f314160d6abcfbcd", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "ws-server/Dockerfile"}, "region": {"startLine": 1}}}]}, {"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-30d7f74fd3581c9c", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/scripts/a_settings.js:143"}, "properties": {"repobilityId": "701053c95455e1d6", "scanner": "scanner-primary", "fingerprint": "30d7f74fd3581c9c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel/scripts/a_settings.js"}, "region": {"startLine": 143}}}]}, {"ruleId": "scanner-7c8b15276ea25147", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/scripts/initials.js:7"}, "properties": {"repobilityId": "8862e3054089578c", "scanner": "scanner-primary", "fingerprint": "7c8b15276ea25147", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel/scripts/initials.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-2a69f82e626eb562", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/admin/scripts/users.js:55"}, "properties": {"repobilityId": "abcd41c1eb1b86a6", "scanner": "scanner-primary", "fingerprint": "2a69f82e626eb562", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel/admin/scripts/users.js"}, "region": {"startLine": 55}}}]}, {"ruleId": "scanner-3826b59ad7cb0735", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in panel/admin/scripts/companies.js:81"}, "properties": {"repobilityId": "4e9d0a18d4200429", "scanner": "scanner-primary", "fingerprint": "3826b59ad7cb0735", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel/admin/scripts/companies.js"}, "region": {"startLine": 81}}}]}, {"ruleId": "scanner-8b3517035e482b8e", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in screens/scripts/kds.js:408"}, "properties": {"repobilityId": "ac5765b0bcfa40d8", "scanner": "scanner-primary", "fingerprint": "8b3517035e482b8e", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "screens/scripts/kds.js"}, "region": {"startLine": 408}}}]}, {"ruleId": "scanner-d3e7da95b66eac16", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/scripts/confettiKit.min.js:1"}, "properties": {"repobilityId": "b6cd493843f3c980", "scanner": "scanner-primary", "fingerprint": "d3e7da95b66eac16", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/scripts/confettiKit.min.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-1e34ef8322965417", "level": "error", "message": {"text": "Possible secret in app/scripts/sign-message.js"}, "properties": {"repobilityId": "31cc79fe4edce4b8", "scanner": "scanner-primary", "fingerprint": "1e34ef8322965417", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/scripts/sign-message.js"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-d7f1c4a40e57cf72", "level": "error", "message": {"text": "Insecure pattern 'private_key_in_repo' in app/scripts/sign-message.js:41"}, "properties": {"repobilityId": "4184761203b61f6f", "scanner": "scanner-primary", "fingerprint": "d7f1c4a40e57cf72", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["owasp", "private_key_in_repo"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/scripts/sign-message.js"}, "region": {"startLine": 41}}}]}, {"ruleId": "scanner-5e3d57374a959d18", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in app/scripts/enjoyhint.min.js:2"}, "properties": {"repobilityId": "d5ab3d0c5e142d6d", "scanner": "scanner-primary", "fingerprint": "5e3d57374a959d18", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/scripts/enjoyhint.min.js"}, "region": {"startLine": 2}}}]}, {"ruleId": "scanner-a4d1683d2507f017", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in panel-next/components/ui/chart.tsx:95"}, "properties": {"repobilityId": "f943a19b7853171d", "scanner": "scanner-primary", "fingerprint": "a4d1683d2507f017", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "panel-next/components/ui/chart.tsx"}, "region": {"startLine": 95}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9df8e08a95a059d9", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 28}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "989a74409a402368", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 85}}}]}, {"ruleId": "scanner-27924aa79fa4a517", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "9df8e08a95a059d9", "scanner": "scanner-primary", "fingerprint": "27924aa79fa4a517", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/ci.yml"}, "region": {"startLine": 136}}}]}, {"ruleId": "scanner-2901abac05ac78ac", "level": "note", "message": {"text": "Very large file: panel/scripts/common.js (6202 lines)"}, "properties": {"repobilityId": "c06a4cc868f9db2e", "scanner": "scanner-primary", "fingerprint": "2901abac05ac78ac", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2083d312e4c1a878", "level": "note", "message": {"text": "Very large file: panel/cgi-bin/common.js (4271 lines)"}, "properties": {"repobilityId": "d524140613b3c30e", "scanner": "scanner-primary", "fingerprint": "2083d312e4c1a878", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2b075fde1a9f1368", "level": "note", "message": {"text": "Very large file: panel-next/app/(panel)/items/[id]/page.tsx (1738 lines)"}, "properties": {"repobilityId": "bbb5c33d35c23d1d", "scanner": "scanner-primary", "fingerprint": "2b075fde1a9f1368", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-060d742a23641893", "level": "note", "message": {"text": "Very large file: panel-next/app/(panel)/contacts/[id]/page.tsx (1671 lines)"}, "properties": {"repobilityId": "8d6d9b782dd8648f", "scanner": "scanner-primary", "fingerprint": "060d742a23641893", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-09139f0da0f0bf07", "level": "note", "message": {"text": "86 TODO/FIXME markers"}, "properties": {"repobilityId": "4b38c118003e07d2", "scanner": "scanner-primary", "fingerprint": "09139f0da0f0bf07", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["maintenance"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "4bb50758f4305e7d", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "63afbee27b4a03e4", "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": "dc505db99c8c486e", "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": "40beaae6711dda2c", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-11825279136b53a3", "level": "warning", "message": {"text": "CI is configured but no tests are detected"}, "properties": {"repobilityId": "780c133d61dd7eda", "scanner": "scanner-primary", "fingerprint": "11825279136b53a3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "ci", "config-theater", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "76fb5a2a1b9b3b6c", "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": "cfcac7ff3f80995d", "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": "e84cbc99eff2e0bb", "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": "ec762d579b2e3eb9", "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-2c5f98b152cddb6d", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/launch.json"}, "properties": {"repobilityId": "0de48c0f4ab303d8", "scanner": "scanner-primary", "fingerprint": "2c5f98b152cddb6d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/launch.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-5c57430bbab4ee58", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/agents/context-updater.md"}, "properties": {"repobilityId": "4a33d72944f706d1", "scanner": "scanner-primary", "fingerprint": "5c57430bbab4ee58", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/agents/context-updater.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4354d75702005889", "level": "note", "message": {"text": "Legacy-named symbol `customersOld` in panel/scripts/a_report_dashboard.js:39"}, "properties": {"repobilityId": "053e2a4e06f270ad", "scanner": "scanner-primary", "fingerprint": "4354d75702005889", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-aee783b2db81dfd9", "level": "none", "message": {"text": "Commented-code block (6 lines) in panel/scripts/a_report_dashboard.js:422"}, "properties": {"repobilityId": "dfae30faeca5a4ee", "scanner": "scanner-primary", "fingerprint": "aee783b2db81dfd9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5261d1a790e66b31", "level": "note", "message": {"text": "Legacy-named symbol `maskDigitPosMapOld` in panel/scripts/initials.js:27"}, "properties": {"repobilityId": "097733f39c7b5b90", "scanner": "scanner-primary", "fingerprint": "5261d1a790e66b31", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-3c5efcdebe056444", "level": "note", "message": {"text": "Legacy-named symbol `content_copy` in panel/scripts/a_settings_templates.js:307"}, "properties": {"repobilityId": "5e37b0748eda95de", "scanner": "scanner-primary", "fingerprint": "3c5efcdebe056444", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-38b088a028359231", "level": "none", "message": {"text": "Commented-code block (16 lines) in panel/scripts/common.js:1144"}, "properties": {"repobilityId": "614ba937a195ff11", "scanner": "scanner-primary", "fingerprint": "38b088a028359231", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-8fad21d2c53d863b", "level": "note", "message": {"text": "Legacy-named symbol `content_copy` in panel/scripts/a_settings2.js:1"}, "properties": {"repobilityId": "9a333437795f4913", "scanner": "scanner-primary", "fingerprint": "8fad21d2c53d863b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-75bf1e2cc8f29f72", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/api/items.js:4"}, "properties": {"repobilityId": "962a8ca3bb60295c", "scanner": "scanner-primary", "fingerprint": "75bf1e2cc8f29f72", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-59d3818e877774ab", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/api/contacts.js:4"}, "properties": {"repobilityId": "0cc8359a5a56d170", "scanner": "scanner-primary", "fingerprint": "59d3818e877774ab", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-72e98d24b16bbdd1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/items/form.js:22"}, "properties": {"repobilityId": "2790f4be4bfa10a9", "scanner": "scanner-primary", "fingerprint": "72e98d24b16bbdd1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-ab74250b1037963e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/scripts/contacts/form.js:33"}, "properties": {"repobilityId": "280ff16a6ee9807c", "scanner": "scanner-primary", "fingerprint": "ab74250b1037963e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b8eae3033e02fd28", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/admin/scripts/users.js:47"}, "properties": {"repobilityId": "fd351e3cb9ade386", "scanner": "scanner-primary", "fingerprint": "b8eae3033e02fd28", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2497b1f3825687bf", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel/admin/scripts/companies.js:58"}, "properties": {"repobilityId": "2e4d7f31f8cf090a", "scanner": "scanner-primary", "fingerprint": "2497b1f3825687bf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f02ab25ed6f96b7c", "level": "none", "message": {"text": "Commented-code block (16 lines) in panel/cgi-bin/common.js:565"}, "properties": {"repobilityId": "0e63869e7c5203f4", "scanner": "scanner-primary", "fingerprint": "f02ab25ed6f96b7c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c8ae0098f6b2dd0c", "level": "note", "message": {"text": "Legacy-named symbol `copyOld` in screens/scripts/cds.js:264"}, "properties": {"repobilityId": "d0a2062715c0b9f2", "scanner": "scanner-primary", "fingerprint": "c8ae0098f6b2dd0c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-11851e8d2b96a07c", "level": "note", "message": {"text": "Legacy-named symbol `copyOld` in screens/scripts/kds.js:267"}, "properties": {"repobilityId": "c7e33f28cf1c36f8", "scanner": "scanner-primary", "fingerprint": "11851e8d2b96a07c", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-a61c0ee31a049d55", "level": "none", "message": {"text": "Commented-code block (8 lines) in app-next/components/ui/money-input.tsx:51"}, "properties": {"repobilityId": "efe1a53843dfaa42", "scanner": "scanner-primary", "fingerprint": "a61c0ee31a049d55", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-58a53eae8f84f795", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app-next/lib/api-client.ts:62"}, "properties": {"repobilityId": "89ae50bd471a24da", "scanner": "scanner-primary", "fingerprint": "58a53eae8f84f795", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-392fe45eb5abc3b0", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/components/layout/panel-auth-guard.tsx:21"}, "properties": {"repobilityId": "b3473c2e55c5cbd0", "scanner": "scanner-primary", "fingerprint": "392fe45eb5abc3b0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f21acf8e3fed786c", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/components/layout/app-sidebar.tsx:261"}, "properties": {"repobilityId": "71abcb79e264ff46", "scanner": "scanner-primary", "fingerprint": "f21acf8e3fed786c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e04cd5a1451432d2", "level": "none", "message": {"text": "Commented-code block (8 lines) in panel-next/components/ui/money-input.tsx:52"}, "properties": {"repobilityId": "dfb3529337c6e25e", "scanner": "scanner-primary", "fingerprint": "e04cd5a1451432d2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e81abbeb2e2a3ac8", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/components/print-templates/canvas-block.tsx:161"}, "properties": {"repobilityId": "349d551423dd4fef", "scanner": "scanner-primary", "fingerprint": "e81abbeb2e2a3ac8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ac9b816c1d7a8f48", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/app/api/admin/[...path]/route.ts:170"}, "properties": {"repobilityId": "5e8d325837dc649f", "scanner": "scanner-primary", "fingerprint": "ac9b816c1d7a8f48", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-44c91bb9d8e91338", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/app/(panel)/page.tsx:102"}, "properties": {"repobilityId": "c6372d530ba65489", "scanner": "scanner-primary", "fingerprint": "44c91bb9d8e91338", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c6d0966f3f51987f", "level": "none", "message": {"text": "Commented-code block (6 lines) in panel-next/app/(panel)/settings/page.tsx:245"}, "properties": {"repobilityId": "5fac24cb83e9535d", "scanner": "scanner-primary", "fingerprint": "c6d0966f3f51987f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-340a6c62e8e48269", "level": "none", "message": {"text": "Commented-code block (6 lines) in panel-next/app/(panel)/reports/summary/page.tsx:61"}, "properties": {"repobilityId": "4bd97f36753bb49d", "scanner": "scanner-primary", "fingerprint": "340a6c62e8e48269", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4d6cdaa30a943627", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/app/(auth)/signup/page.tsx:83"}, "properties": {"repobilityId": "8ba8e84ba392585c", "scanner": "scanner-primary", "fingerprint": "4d6cdaa30a943627", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3acd3d92b3473a53", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/app/(auth)/signup/page.tsx:90"}, "properties": {"repobilityId": "29df0b0ccbcf9fe6", "scanner": "scanner-primary", "fingerprint": "3acd3d92b3473a53", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1aa0fae2af49c3e8", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/lib/api-client.ts:53"}, "properties": {"repobilityId": "74cbfab8c6a593b3", "scanner": "scanner-primary", "fingerprint": "1aa0fae2af49c3e8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b442f038cd6fcbd8", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/lib/api-client.ts:83"}, "properties": {"repobilityId": "54b0b0c9272d5a85", "scanner": "scanner-primary", "fingerprint": "b442f038cd6fcbd8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5e4b6b40bdbd32e3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/lib/api-admin.ts:44"}, "properties": {"repobilityId": "1e0f4c233f33132f", "scanner": "scanner-primary", "fingerprint": "5e4b6b40bdbd32e3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-b996c3fe63369de1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 panel-next/hooks/use-dashboard-widget.ts:137"}, "properties": {"repobilityId": "c0402dfba9d3521f", "scanner": "scanner-primary", "fingerprint": "b996c3fe63369de1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c840fed8e60f434d", "level": "none", "message": {"text": "Commented-code block (5 lines) in panel-next/hooks/use-contacts.ts:191"}, "properties": {"repobilityId": "21645eb9ffd42438", "scanner": "scanner-primary", "fingerprint": "c840fed8e60f434d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-319e66a630e14977", "level": "none", "message": {"text": "2 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "d838d1fc5d8231c9", "scanner": "scanner-primary", "fingerprint": "319e66a630e14977", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-cbe6296fcbe9dde4", "level": "error", "message": {"text": "Dangling fetch: POST /bff/admin/login.php (panel/admin/scripts/login.js:21)"}, "properties": {"repobilityId": "39dd4401c56e8e86", "scanner": "scanner-primary", "fingerprint": "cbe6296fcbe9dde4", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-462bf6e822d0b466", "level": "error", "message": {"text": "Dangling fetch: POST /bff/admin/logout.php (panel/admin/scripts/users.js:117)"}, "properties": {"repobilityId": "1472f55a2e13895d", "scanner": "scanner-primary", "fingerprint": "462bf6e822d0b466", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-355cb4dff5978cad", "level": "error", "message": {"text": "Dangling fetch: POST /bff/admin/companies.php?action=resolveRequest (panel/admin/scripts/companies.js:502)"}, "properties": {"repobilityId": "168aaf6ff0be15a1", "scanner": "scanner-primary", "fingerprint": "355cb4dff5978cad", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8ce79731f3793fb5", "level": "error", "message": {"text": "Dangling fetch: POST /bff/admin/logout.php (panel/admin/scripts/companies.js:771)"}, "properties": {"repobilityId": "1f2a63818b71a1bd", "scanner": "scanner-primary", "fingerprint": "8ce79731f3793fb5", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-49302075ff4efeda", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/users.php (panel-next/hooks/use-admin.ts:385)"}, "properties": {"repobilityId": "d9f0b916691f4f9f", "scanner": "scanner-primary", "fingerprint": "49302075ff4efeda", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-474a40573cf00033", "level": "error", "message": {"text": "Dangling fetch: GET /api/dashboard/income-chart?${params.toString()} (panel-next/hooks/use-dashboard-widget.ts:137)"}, "properties": {"repobilityId": "ce83437a4f608105", "scanner": "scanner-primary", "fingerprint": "474a40573cf00033", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-f284425a416887b3", "level": "note", "message": {"text": "Unused endpoint: POST /v1/contacts"}, "properties": {"repobilityId": "9d282a087d917f34", "scanner": "scanner-primary", "fingerprint": "f284425a416887b3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-621911d708fc8af4", "level": "note", "message": {"text": "Unused endpoint: POST /login.php"}, "properties": {"repobilityId": "2d5408bbc3569211", "scanner": "scanner-primary", "fingerprint": "621911d708fc8af4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c19afa1cffd0d4e", "level": "note", "message": {"text": "Unused endpoint: POST /v1/login"}, "properties": {"repobilityId": "67d1601a838ce434", "scanner": "scanner-primary", "fingerprint": "7c19afa1cffd0d4e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a6c305793fd4945d", "level": "note", "message": {"text": "Unused endpoint: POST /v1/signup/start"}, "properties": {"repobilityId": "6166c2243eeb4b19", "scanner": "scanner-primary", "fingerprint": "a6c305793fd4945d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-41da9c4e93e4f746", "level": "note", "message": {"text": "Unused endpoint: POST /v1/signup/verify"}, "properties": {"repobilityId": "6242501937d4e8f6", "scanner": "scanner-primary", "fingerprint": "41da9c4e93e4f746", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-62ad4c8c63e50e6d", "level": "note", "message": {"text": "Unused endpoint: POST /v1/signup"}, "properties": {"repobilityId": "3c946333eb055906", "scanner": "scanner-primary", "fingerprint": "62ad4c8c63e50e6d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-50821ec1669b6f8a", "level": "note", "message": {"text": "Unused endpoint: GET /v1/brands"}, "properties": {"repobilityId": "773fe465e348e4e5", "scanner": "scanner-primary", "fingerprint": "50821ec1669b6f8a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3be1d0dfb76d1de7", "level": "note", "message": {"text": "Unused endpoint: GET /v1/taxes"}, "properties": {"repobilityId": "c815f83188c41e5a", "scanner": "scanner-primary", "fingerprint": "3be1d0dfb76d1de7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4e44aad0ef34a79e", "level": "note", "message": {"text": "Unused endpoint: GET /v1/users?resource=roles"}, "properties": {"repobilityId": "58461da52a6e90be", "scanner": "scanner-primary", "fingerprint": "4e44aad0ef34a79e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7a899b0da3a4371d", "level": "note", "message": {"text": "Unused endpoint: GET /v1/categories"}, "properties": {"repobilityId": "a756c6c025078699", "scanner": "scanner-primary", "fingerprint": "7a899b0da3a4371d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-99fc36db98c134ce", "level": "note", "message": {"text": "Unused endpoint: POST /logout"}, "properties": {"repobilityId": "d8a610e6e8976eb3", "scanner": "scanner-primary", "fingerprint": "99fc36db98c134ce", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-70455b9324d77aff", "level": "note", "message": {"text": "Unused endpoint: GET /companies.php?plans=1"}, "properties": {"repobilityId": "b37e9968c9b09b9c", "scanner": "scanner-primary", "fingerprint": "70455b9324d77aff", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-888615f4ba8fd7fd", "level": "note", "message": {"text": "Unused endpoint: POST /companies.php?action=resolveRequest"}, "properties": {"repobilityId": "044323c34317e21a", "scanner": "scanner-primary", "fingerprint": "888615f4ba8fd7fd", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-28a90364d1735211", "level": "note", "message": {"text": "Unused endpoint: GET /users.php"}, "properties": {"repobilityId": "df905f9bdfe1e652", "scanner": "scanner-primary", "fingerprint": "28a90364d1735211", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a1f5eddb14c6ff4a", "level": "note", "message": {"text": "Unused endpoint: POST /v1/items?resource=group"}, "properties": {"repobilityId": "955243671d5051ad", "scanner": "scanner-primary", "fingerprint": "a1f5eddb14c6ff4a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-fe66cb3d660c3885", "level": "note", "message": {"text": "Unused endpoint: POST /v1/items?resource=bulk-edit"}, "properties": {"repobilityId": "ff842ae716c24f51", "scanner": "scanner-primary", "fingerprint": "fe66cb3d660c3885", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0b5757fd94364e3", "level": "note", "message": {"text": "Unused endpoint: GET /v1/taxonomies"}, "properties": {"repobilityId": "3e5d5b1dac38833b", "scanner": "scanner-primary", "fingerprint": "b0b5757fd94364e3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1658c07109ac0cf8", "level": "note", "message": {"text": "Unused endpoint: GET /v1/currencies"}, "properties": {"repobilityId": "92f5832c5e469df4", "scanner": "scanner-primary", "fingerprint": "1658c07109ac0cf8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4bb41679a4d77c01", "level": "note", "message": {"text": "Unused endpoint: GET /v1/settings?view=currencies"}, "properties": {"repobilityId": "5ccd0ae4a9937510", "scanner": "scanner-primary", "fingerprint": "4bb41679a4d77c01", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b81539cd09c337f1", "level": "note", "message": {"text": "Unused endpoint: POST /v1/settings"}, "properties": {"repobilityId": "d34f8abd08dda022", "scanner": "scanner-primary", "fingerprint": "b81539cd09c337f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f704d23a72d234b9", "level": "note", "message": {"text": "Unused endpoint: GET /v1/document-templates"}, "properties": {"repobilityId": "51a61f41ae55293c", "scanner": "scanner-primary", "fingerprint": "f704d23a72d234b9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d401e239f75668d0", "level": "note", "message": {"text": "Unused endpoint: POST /v1/customer_address"}, "properties": {"repobilityId": "b84277a24a1a66b1", "scanner": "scanner-primary", "fingerprint": "d401e239f75668d0", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6e2c5ce35996298f", "level": "note", "message": {"text": "Unused endpoint: POST /v1/modules"}, "properties": {"repobilityId": "398f77aff64f6840", "scanner": "scanner-primary", "fingerprint": "6e2c5ce35996298f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}