{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-bead75b0f9233e05", "name": "No API endpoints detected", "shortDescription": {"text": "No API endpoints detected"}, "fullDescription": {"text": "The scanner did not find FastAPI/Flask/Express/NestJS/GraphQL/gRPC routes. If this repo exposes APIs, the framework may be unsupported."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a11d515fa20a7d2c", "name": "Stray `console.log` in TS/JS \u2014 scripts/diagnose-manager-trade.ts:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/diagnose-manager-trade.ts:25"}, "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-fb520dcd81bffc1d", "name": "Stray `console.log` in TS/JS \u2014 scripts/import-team-leaders.ts:55", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-team-leaders.ts:55"}, "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-eb46194c63a622f8", "name": "Stray `console.log` in TS/JS \u2014 scripts/inspect-masonry-seed.ts:10", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-masonry-seed.ts:10"}, "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-0738563b97c08d5a", "name": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-site-managers.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-site-managers.ts:36"}, "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-26bbddda75c2eb91", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-masonry-sample.ts:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-masonry-sample.ts:46"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9028532650f09206", "name": "Stray `console.log` in TS/JS \u2014 scripts/clean-template.ts:15", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/clean-template.ts:15"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a966d6bed25298f3", "name": "Stray `console.log` in TS/JS \u2014 scripts/check-sm-trade.ts:11", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-sm-trade.ts:11"}, "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-3f139d02b3b55f60", "name": "Stray `console.log` in TS/JS \u2014 scripts/fill-site-manager-phones.ts:48", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/fill-site-manager-phones.ts:48"}, "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-df7f1b5988a76c9f", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-gocheon-sample.ts:64", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-gocheon-sample.ts:64"}, "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-6033bdf932d9ff2d", "name": "Stray `console.log` in TS/JS \u2014 scripts/import-workers-master.ts:132", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-workers-master.ts:132"}, "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-4f3e64e93724358d", "name": "TODO/FIXME marker in shipping code \u2014 scripts/seed-worksites.ts:18", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 scripts/seed-worksites.ts:18"}, "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-a4f191aed0ef00c4", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-worksites.ts:41", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-worksites.ts:41"}, "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-8829ffe2bdeaa069", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:22", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:22"}, "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-8a14b65ceb07e752", "name": "Stray `console.log` in TS/JS \u2014 scripts/inspect-report.ts:11", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-report.ts:11"}, "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-507b01e1a8c620a6", "name": "Stray `console.log` in TS/JS \u2014 scripts/inspect-xlsx-cols.ts:12", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-xlsx-cols.ts:12"}, "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-ea4f37d674f5f059", "name": "Stray `console.log` in TS/JS \u2014 scripts/inspect-dn.ts:9", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-dn.ts:9"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-9b30ebc47a0f469f", "name": "Stray `console.log` in TS/JS \u2014 scripts/test-fill.ts:59", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-fill.ts:59"}, "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-a3b35bb168cf8d74", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-mock-attendance.ts:36", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-mock-attendance.ts:36"}, "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-421d8c738cf14cf1", "name": "Stray `console.log` in TS/JS \u2014 scripts/verify-audit-trigger.ts:23", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/verify-audit-trigger.ts:23"}, "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-6acc791b0de11f29", "name": "Stray `console.log` in TS/JS \u2014 scripts/migrate-pin-passwords.ts:35", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/migrate-pin-passwords.ts:35"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dc4c83fd26eaf51d", "name": "Stray `console.log` in TS/JS \u2014 scripts/seed-full-payroll.ts:46", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-full-payroll.ts:46"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a386f0434f75458c", "name": "Stray `console.log` in TS/JS \u2014 scripts/verify-team-leaders-vs-workers.ts:151", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/verify-team-leaders-vs-workers.ts:151"}, "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-282331f4c56ba7fb", "name": "Stray `console.log` in TS/JS \u2014 scripts/import-workers.ts:43", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-workers.ts:43"}, "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-eb520c9a5d8afa63", "name": "Stray `console.log` in TS/JS \u2014 scripts/inspect-team-leaders-xlsx.ts:8", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-team-leaders-xlsx.ts:8"}, "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-10b99d8d9e01f3af", "name": "Stray `console.log` in TS/JS \u2014 scripts/extract-workers-fixture.ts:75", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/extract-workers-fixture.ts:75"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b9436dbcb5ee5908", "name": "Stray `console.log` in TS/JS \u2014 scripts/diagnose-leader-conflict.ts:43", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/diagnose-leader-conflict.ts:43"}, "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-8b93e42dd8528e21", "name": "Stray `console.log` in TS/JS \u2014 scripts/import-team-leaders-to-workers.ts:119", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-team-leaders-to-workers.ts:119"}, "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-62c7b7e35e46207a", "name": "Stray `console.log` in TS/JS \u2014 scripts/verify-workers-master.ts:199", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/verify-workers-master.ts:199"}, "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-393478e36193a24c", "name": "Stray `console.log` in TS/JS \u2014 scripts/check-team-leaders-presence.ts:39", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-team-leaders-presence.ts:39"}, "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-f2ae9f02805d779c", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/manager-volumes-review.tsx:152", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/manager-volumes-review.tsx:152"}, "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-0b1794222d3a7687", "name": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/volumes-form.tsx:156", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/volumes-form.tsx:156"}, "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-0a2fecbcef3f6f60", "name": "`truncate` class without `title=` for hover reveal \u2014 app/notifications/page.tsx:282", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/notifications/page.tsx:282"}, "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-bee71236fc56c2b5", "name": "`truncate` class without `title=` for hover reveal \u2014 app/dashboard/page.tsx:186", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/dashboard/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-c3072b1664b2f537", "name": "`truncate` class without `title=` for hover reveal \u2014 app/vendors/page.tsx:107", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/vendors/page.tsx:107"}, "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-f472ab78c3fcceb2", "name": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/orders/page.tsx:224", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/orders/page.tsx:224"}, "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-3c021cd2e1940a31", "name": "\"active\" state uses light bg in a dark theme \u2014 app/m/manager/orders/page.tsx:238", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/m/manager/orders/page.tsx:238"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-92e0ec6f12d0fa07", "name": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/home/page.tsx:267", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/home/page.tsx:267"}, "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-01c4b831397771b6", "name": "Stray `console.log` in TS/JS \u2014 app/m/manager/home/page.tsx:219", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 app/m/manager/home/page.tsx:219"}, "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-06fa64f7fa15231e", "name": "\"active\" state uses light bg in a dark theme \u2014 app/m/manager/volumes/page.tsx:101", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/m/manager/volumes/page.tsx:101"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-09eba2c7c78f6ef6", "name": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/site-gps/page.tsx:308", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/site-gps/page.tsx:308"}, "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-1bffab12bc2a95e6", "name": "\"active\" state uses light bg in a dark theme \u2014 app/payroll/payroll-tabs.tsx:49", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/payroll/payroll-tabs.tsx:49"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-36d9e9ae656b3eff", "name": "\"active\" state uses light bg in a dark theme \u2014 app/announcements/page.tsx:350", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/announcements/page.tsx:350"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3bb3473f5a271210", "name": "`truncate` class without `title=` for hover reveal \u2014 app/attendance/page.tsx:246", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/attendance/page.tsx:246"}, "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-2d1508fc83649404", "name": "`truncate` class without `title=` for hover reveal \u2014 app/expenses/page.tsx:472", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/expenses/page.tsx:472"}, "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-2ee230b290ab3372", "name": "Stray `console.log` in TS/JS \u2014 e2e/global-teardown.ts:87", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 e2e/global-teardown.ts:87"}, "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-99646d7ff28a8f7c", "name": "Stray `console.log` in TS/JS \u2014 e2e/global-setup.ts:114", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 e2e/global-setup.ts:114"}, "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-ed2590c6cbbe373f", "name": "Possible secret in e2e/helpers/e2e-env.ts", "shortDescription": {"text": "Possible secret in e2e/helpers/e2e-env.ts"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "1 test file(s) for 260 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 240 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 124 placeholder/mock markers across 36 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci. 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, ci. 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-e725d2ab884fbd49", "name": "Multiple root agent instruction files without precedence", "shortDescription": {"text": "Multiple root agent instruction files without precedence"}, "fullDescription": {"text": "The repo has multiple top-level AI-coder instruction files. Without precedence rules, different agents may follow different policies."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8e3c11c425957118", "name": "Commented-code block (5 lines) in scripts/seed-masonry-sample.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/seed-masonry-sample.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-782ac9ef77d908d7", "name": "Commented-code block (6 lines) in scripts/seed-gocheon-sample.ts:1", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/seed-gocheon-sample.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-e6849df253155d38", "name": "`fetch()` without try/.catch or AbortSignal \u2014 components/mobile/document-uploader.tsx:235", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 components/mobile/document-uploader.tsx:235"}, "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-4108a4ecb64285f3", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/company/page.tsx:25", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/company/page.tsx:25"}, "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-0749fdb1de34ca6e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/account/page.tsx:29", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/account/page.tsx:29"}, "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-eee29cab08649724", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/members/page.tsx:55", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/members/page.tsx:55"}, "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-7df0b092603f8acf", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/notifications/page.tsx:71", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/notifications/page.tsx:71"}, "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-c5c41e7ebe757647", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/monitoring/volumes-review/page.tsx:67", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/monitoring/volumes-review/page.tsx:67"}, "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-4e9a7c7feb67594f", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/monitoring/attendance-review/page.tsx:78", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/monitoring/attendance-review/page.tsx:78"}, "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-35f59d00841fe694", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/orders/page.tsx:63", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/orders/page.tsx:63"}, "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-e1eba9557225ff6b", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/dashboard/page.tsx:50", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/dashboard/page.tsx:50"}, "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-302fa6f6ca860629", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/vendors/page.tsx:38", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/vendors/page.tsx:38"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-563bb5b12a52d911", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/m/manager/assignments/page.tsx:56", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/m/manager/assignments/page.tsx:56"}, "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-08148d7a54d0466c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/subcontractors/page.tsx:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/subcontractors/page.tsx:18"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-079ad288faab66a2", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/payroll/[siteId]/[yyyymm]/grid.tsx:84", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/payroll/[siteId]/[yyyymm]/grid.tsx:84"}, "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-4fb4dd8b13e43641", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/workers/page.tsx:56", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/workers/page.tsx:56"}, "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-2ca8da5cf81025c9", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/announcements/page.tsx:59", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/announcements/page.tsx:59"}, "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-f27ec83ec2f581c1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/admin/audit-log/page.tsx:88", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/admin/audit-log/page.tsx:88"}, "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-e42bd6854940b483", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/admin/site-photos/page.tsx:105", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/admin/site-photos/page.tsx:105"}, "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-d3638b78cd73fd8e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/attendance/page.tsx:72", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/attendance/page.tsx:72"}, "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-30e0e7013d398386", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/masonry-prices/page.tsx:35", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/masonry-prices/page.tsx:35"}, "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-f24032f250173ffb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/expenses/page.tsx:87", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/expenses/page.tsx:87"}, "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-932084a315b9e29e", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/clients/page.tsx:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/clients/page.tsx:18"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9fa984538a97ad2d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/items/page.tsx:84", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/items/page.tsx:84"}, "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-0abaa4460d3550c4", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/trades/page.tsx:26", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/trades/page.tsx:26"}, "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-fed83ccba962bf1d", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/worksites/page.tsx:21", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/worksites/page.tsx:21"}, "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-82caf4719f84ea67", "name": "`fetch()` without try/.catch or AbortSignal \u2014 app/managers/page.tsx:85", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/managers/page.tsx:85"}, "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-aafcfefa43aff952", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/receipt-ocr.ts:73", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/receipt-ocr.ts:73"}, "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-d7c7bbdb919e7b59", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/manager/mirror.ts:15", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/manager/mirror.ts:15"}, "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-de809baf10f182cc", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/utils/download.ts:13", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/utils/download.ts:13"}, "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-8ba5a71e23b15f73", "name": "Commented-code block (6 lines) in lib/capacitor/tracking.ts:1", "shortDescription": {"text": "Commented-code block (6 lines) in lib/capacitor/tracking.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-02bd53274042ad8a", "name": "`fetch()` without try/.catch or AbortSignal \u2014 lib/capacitor/photo-picker.ts:20", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/capacitor/photo-picker.ts:20"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-dab453049c8e70f0", "name": "Commented-code block (5 lines) in lib/audit/format.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in lib/audit/format.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-da266b6062007050", "name": "Commented-code block (5 lines) in lib/payroll/calc.ts:1", "shortDescription": {"text": "Commented-code block (5 lines) in lib/payroll/calc.ts:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2074c1203d5921ce", "name": "Commented-code block (5 lines) in lib/excel/fill-payroll.ts:103", "shortDescription": {"text": "Commented-code block (5 lines) in lib/excel/fill-payroll.ts:103"}, "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}}]}}, "automationDetails": {"id": "repobility/17934"}, "properties": {"repository": "realks2002-cell/yeseong", "repoUrl": "https://github.com/realks2002-cell/yeseong", "branch": "main"}, "results": [{"ruleId": "scanner-bead75b0f9233e05", "level": "none", "message": {"text": "No API endpoints detected"}, "properties": {"repobilityId": "0f8bb852027c38f8", "scanner": "scanner-primary", "fingerprint": "bead75b0f9233e05", "layer": "api", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-a11d515fa20a7d2c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/diagnose-manager-trade.ts:25"}, "properties": {"repobilityId": "56b733537c6a0cb4", "scanner": "scanner-primary", "fingerprint": "a11d515fa20a7d2c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-fb520dcd81bffc1d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-team-leaders.ts:55"}, "properties": {"repobilityId": "03097a667699dceb", "scanner": "scanner-primary", "fingerprint": "fb520dcd81bffc1d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-eb46194c63a622f8", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-masonry-seed.ts:10"}, "properties": {"repobilityId": "95ff1982223ae844", "scanner": "scanner-primary", "fingerprint": "eb46194c63a622f8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0738563b97c08d5a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cleanup-site-managers.ts:36"}, "properties": {"repobilityId": "b64faf7874b44026", "scanner": "scanner-primary", "fingerprint": "0738563b97c08d5a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-26bbddda75c2eb91", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-masonry-sample.ts:46"}, "properties": {"repobilityId": "edb52988455280d9", "scanner": "scanner-primary", "fingerprint": "26bbddda75c2eb91", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9028532650f09206", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/clean-template.ts:15"}, "properties": {"repobilityId": "9936d78789b362f9", "scanner": "scanner-primary", "fingerprint": "9028532650f09206", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a966d6bed25298f3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-sm-trade.ts:11"}, "properties": {"repobilityId": "4a55c662e1f114c3", "scanner": "scanner-primary", "fingerprint": "a966d6bed25298f3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-3f139d02b3b55f60", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/fill-site-manager-phones.ts:48"}, "properties": {"repobilityId": "91d2bbb5283f8ecc", "scanner": "scanner-primary", "fingerprint": "3f139d02b3b55f60", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-df7f1b5988a76c9f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-gocheon-sample.ts:64"}, "properties": {"repobilityId": "575c248ca8db9439", "scanner": "scanner-primary", "fingerprint": "df7f1b5988a76c9f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6033bdf932d9ff2d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-workers-master.ts:132"}, "properties": {"repobilityId": "c7d2e52e310beff2", "scanner": "scanner-primary", "fingerprint": "6033bdf932d9ff2d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4f3e64e93724358d", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 scripts/seed-worksites.ts:18"}, "properties": {"repobilityId": "6bdeaa28434c63be", "scanner": "scanner-primary", "fingerprint": "4f3e64e93724358d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-a4f191aed0ef00c4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-worksites.ts:41"}, "properties": {"repobilityId": "fcef9888a837a04f", "scanner": "scanner-primary", "fingerprint": "a4f191aed0ef00c4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8829ffe2bdeaa069", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed.ts:22"}, "properties": {"repobilityId": "6b45b8d4fff61a2c", "scanner": "scanner-primary", "fingerprint": "8829ffe2bdeaa069", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8a14b65ceb07e752", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-report.ts:11"}, "properties": {"repobilityId": "3eb87a09ffd82b17", "scanner": "scanner-primary", "fingerprint": "8a14b65ceb07e752", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-507b01e1a8c620a6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-xlsx-cols.ts:12"}, "properties": {"repobilityId": "c2025c37b83d5f08", "scanner": "scanner-primary", "fingerprint": "507b01e1a8c620a6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ea4f37d674f5f059", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-dn.ts:9"}, "properties": {"repobilityId": "34123ca453b5ff65", "scanner": "scanner-primary", "fingerprint": "ea4f37d674f5f059", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9b30ebc47a0f469f", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/test-fill.ts:59"}, "properties": {"repobilityId": "916e5138abb9d1f1", "scanner": "scanner-primary", "fingerprint": "9b30ebc47a0f469f", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a3b35bb168cf8d74", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-mock-attendance.ts:36"}, "properties": {"repobilityId": "4e704039531283ee", "scanner": "scanner-primary", "fingerprint": "a3b35bb168cf8d74", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-421d8c738cf14cf1", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/verify-audit-trigger.ts:23"}, "properties": {"repobilityId": "5298a6896a723e24", "scanner": "scanner-primary", "fingerprint": "421d8c738cf14cf1", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6acc791b0de11f29", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/migrate-pin-passwords.ts:35"}, "properties": {"repobilityId": "0a3f625779d295af", "scanner": "scanner-primary", "fingerprint": "6acc791b0de11f29", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-dc4c83fd26eaf51d", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/seed-full-payroll.ts:46"}, "properties": {"repobilityId": "7015608268ba4b75", "scanner": "scanner-primary", "fingerprint": "dc4c83fd26eaf51d", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a386f0434f75458c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/verify-team-leaders-vs-workers.ts:151"}, "properties": {"repobilityId": "502ff78c02f6f2d5", "scanner": "scanner-primary", "fingerprint": "a386f0434f75458c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-282331f4c56ba7fb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-workers.ts:43"}, "properties": {"repobilityId": "f91bfc9069c05d88", "scanner": "scanner-primary", "fingerprint": "282331f4c56ba7fb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-eb520c9a5d8afa63", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/inspect-team-leaders-xlsx.ts:8"}, "properties": {"repobilityId": "403cc8ec51b505f8", "scanner": "scanner-primary", "fingerprint": "eb520c9a5d8afa63", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-10b99d8d9e01f3af", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/extract-workers-fixture.ts:75"}, "properties": {"repobilityId": "2d2d0d1c01f6d61a", "scanner": "scanner-primary", "fingerprint": "10b99d8d9e01f3af", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b9436dbcb5ee5908", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/diagnose-leader-conflict.ts:43"}, "properties": {"repobilityId": "85e9c5502fad64de", "scanner": "scanner-primary", "fingerprint": "b9436dbcb5ee5908", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8b93e42dd8528e21", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/import-team-leaders-to-workers.ts:119"}, "properties": {"repobilityId": "6740a29cc6b0e1aa", "scanner": "scanner-primary", "fingerprint": "8b93e42dd8528e21", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-62c7b7e35e46207a", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/verify-workers-master.ts:199"}, "properties": {"repobilityId": "4c1d9c4871825b16", "scanner": "scanner-primary", "fingerprint": "62c7b7e35e46207a", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-393478e36193a24c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/check-team-leaders-presence.ts:39"}, "properties": {"repobilityId": "51a3cd3f06ddb126", "scanner": "scanner-primary", "fingerprint": "393478e36193a24c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f2ae9f02805d779c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/manager-volumes-review.tsx:152"}, "properties": {"repobilityId": "a31519d57e778084", "scanner": "scanner-primary", "fingerprint": "f2ae9f02805d779c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0b1794222d3a7687", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 components/mobile/volumes-form.tsx:156"}, "properties": {"repobilityId": "395b515d0d8fc2c1", "scanner": "scanner-primary", "fingerprint": "0b1794222d3a7687", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0a2fecbcef3f6f60", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/notifications/page.tsx:282"}, "properties": {"repobilityId": "6e23ea78f6125497", "scanner": "scanner-primary", "fingerprint": "0a2fecbcef3f6f60", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bee71236fc56c2b5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/dashboard/page.tsx:186"}, "properties": {"repobilityId": "49f13da6b8e12b22", "scanner": "scanner-primary", "fingerprint": "bee71236fc56c2b5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c3072b1664b2f537", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/vendors/page.tsx:107"}, "properties": {"repobilityId": "d003e95d788d3515", "scanner": "scanner-primary", "fingerprint": "c3072b1664b2f537", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f472ab78c3fcceb2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/orders/page.tsx:224"}, "properties": {"repobilityId": "80c3e1efdab6e816", "scanner": "scanner-primary", "fingerprint": "f472ab78c3fcceb2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3c021cd2e1940a31", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/m/manager/orders/page.tsx:238"}, "properties": {"repobilityId": "adb8fefc46fa95cc", "scanner": "scanner-primary", "fingerprint": "3c021cd2e1940a31", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-92e0ec6f12d0fa07", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/home/page.tsx:267"}, "properties": {"repobilityId": "fba9ca5343226078", "scanner": "scanner-primary", "fingerprint": "92e0ec6f12d0fa07", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-01c4b831397771b6", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 app/m/manager/home/page.tsx:219"}, "properties": {"repobilityId": "8e8ad7de5790ba79", "scanner": "scanner-primary", "fingerprint": "01c4b831397771b6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-06fa64f7fa15231e", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/m/manager/volumes/page.tsx:101"}, "properties": {"repobilityId": "964030c6240cfc28", "scanner": "scanner-primary", "fingerprint": "06fa64f7fa15231e", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-09eba2c7c78f6ef6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/m/manager/site-gps/page.tsx:308"}, "properties": {"repobilityId": "689e6b180d768a0b", "scanner": "scanner-primary", "fingerprint": "09eba2c7c78f6ef6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1bffab12bc2a95e6", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/payroll/payroll-tabs.tsx:49"}, "properties": {"repobilityId": "e4f01857b42f0f9b", "scanner": "scanner-primary", "fingerprint": "1bffab12bc2a95e6", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-36d9e9ae656b3eff", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 app/announcements/page.tsx:350"}, "properties": {"repobilityId": "23fb7a5678a4e6d1", "scanner": "scanner-primary", "fingerprint": "36d9e9ae656b3eff", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-3bb3473f5a271210", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/attendance/page.tsx:246"}, "properties": {"repobilityId": "1144ae4dacf868a0", "scanner": "scanner-primary", "fingerprint": "3bb3473f5a271210", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2d1508fc83649404", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 app/expenses/page.tsx:472"}, "properties": {"repobilityId": "091b15c467bd7cac", "scanner": "scanner-primary", "fingerprint": "2d1508fc83649404", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2ee230b290ab3372", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 e2e/global-teardown.ts:87"}, "properties": {"repobilityId": "dd8d374e880f9ae4", "scanner": "scanner-primary", "fingerprint": "2ee230b290ab3372", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-99646d7ff28a8f7c", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 e2e/global-setup.ts:114"}, "properties": {"repobilityId": "47b4f7ec079f9271", "scanner": "scanner-primary", "fingerprint": "99646d7ff28a8f7c", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ed2590c6cbbe373f", "level": "error", "message": {"text": "Possible secret in e2e/helpers/e2e-env.ts"}, "properties": {"repobilityId": "d4f45508fc57382b", "scanner": "scanner-primary", "fingerprint": "ed2590c6cbbe373f", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "e2e/helpers/e2e-env.ts"}, "region": {"startLine": 14}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "f15072b9060d6bd3", "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": "c0c5fae5ab1e21ae", "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": "d313229c8efa8879", "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": "b9030912f2bd2d24", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "note", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "fe4632c4bc3df081", "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": "4349d1c34accfa29", "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": "dc59eba9b126067c", "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": "6c5b9aadf5738dc9", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-e725d2ab884fbd49", "level": "note", "message": {"text": "Multiple root agent instruction files without precedence"}, "properties": {"repobilityId": "1953db6c89508d22", "scanner": "scanner-primary", "fingerprint": "e725d2ab884fbd49", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["agent-instructions", "governance"]}}, {"ruleId": "scanner-8e3c11c425957118", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/seed-masonry-sample.ts:1"}, "properties": {"repobilityId": "c4862cbd2d851cd1", "scanner": "scanner-primary", "fingerprint": "8e3c11c425957118", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-782ac9ef77d908d7", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/seed-gocheon-sample.ts:1"}, "properties": {"repobilityId": "8e75fdf454571504", "scanner": "scanner-primary", "fingerprint": "782ac9ef77d908d7", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-e6849df253155d38", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 components/mobile/document-uploader.tsx:235"}, "properties": {"repobilityId": "e64b683582868d36", "scanner": "scanner-primary", "fingerprint": "e6849df253155d38", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4108a4ecb64285f3", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/company/page.tsx:25"}, "properties": {"repobilityId": "22ed439fbdbb7704", "scanner": "scanner-primary", "fingerprint": "4108a4ecb64285f3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0749fdb1de34ca6e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/account/page.tsx:29"}, "properties": {"repobilityId": "d59a231e116189c9", "scanner": "scanner-primary", "fingerprint": "0749fdb1de34ca6e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-eee29cab08649724", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/settings/members/page.tsx:55"}, "properties": {"repobilityId": "e857bc29012abfce", "scanner": "scanner-primary", "fingerprint": "eee29cab08649724", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-7df0b092603f8acf", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/notifications/page.tsx:71"}, "properties": {"repobilityId": "f0c5430496d7ddfd", "scanner": "scanner-primary", "fingerprint": "7df0b092603f8acf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-c5c41e7ebe757647", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/monitoring/volumes-review/page.tsx:67"}, "properties": {"repobilityId": "64d984fedfbbbb0e", "scanner": "scanner-primary", "fingerprint": "c5c41e7ebe757647", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4e9a7c7feb67594f", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/monitoring/attendance-review/page.tsx:78"}, "properties": {"repobilityId": "f43046147e00b7a0", "scanner": "scanner-primary", "fingerprint": "4e9a7c7feb67594f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-35f59d00841fe694", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/orders/page.tsx:63"}, "properties": {"repobilityId": "e1f89b4cd2cf784f", "scanner": "scanner-primary", "fingerprint": "35f59d00841fe694", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e1eba9557225ff6b", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/dashboard/page.tsx:50"}, "properties": {"repobilityId": "a655c5eb7a900b85", "scanner": "scanner-primary", "fingerprint": "e1eba9557225ff6b", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-302fa6f6ca860629", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/vendors/page.tsx:38"}, "properties": {"repobilityId": "74d7e15e8e154f7d", "scanner": "scanner-primary", "fingerprint": "302fa6f6ca860629", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-563bb5b12a52d911", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/m/manager/assignments/page.tsx:56"}, "properties": {"repobilityId": "4080acd37409684a", "scanner": "scanner-primary", "fingerprint": "563bb5b12a52d911", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-08148d7a54d0466c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/subcontractors/page.tsx:18"}, "properties": {"repobilityId": "5c26a84667eaa547", "scanner": "scanner-primary", "fingerprint": "08148d7a54d0466c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-079ad288faab66a2", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/payroll/[siteId]/[yyyymm]/grid.tsx:84"}, "properties": {"repobilityId": "071e66cffe5c5a5c", "scanner": "scanner-primary", "fingerprint": "079ad288faab66a2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-4fb4dd8b13e43641", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/workers/page.tsx:56"}, "properties": {"repobilityId": "a68b68d35f786e90", "scanner": "scanner-primary", "fingerprint": "4fb4dd8b13e43641", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2ca8da5cf81025c9", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/announcements/page.tsx:59"}, "properties": {"repobilityId": "cd152c51edbdb1ec", "scanner": "scanner-primary", "fingerprint": "2ca8da5cf81025c9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f27ec83ec2f581c1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/admin/audit-log/page.tsx:88"}, "properties": {"repobilityId": "6994ec3af8050be4", "scanner": "scanner-primary", "fingerprint": "f27ec83ec2f581c1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e42bd6854940b483", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/admin/site-photos/page.tsx:105"}, "properties": {"repobilityId": "4ed72b0a999fea3d", "scanner": "scanner-primary", "fingerprint": "e42bd6854940b483", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d3638b78cd73fd8e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/attendance/page.tsx:72"}, "properties": {"repobilityId": "d607c6fdc88ec319", "scanner": "scanner-primary", "fingerprint": "d3638b78cd73fd8e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-30e0e7013d398386", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/masonry-prices/page.tsx:35"}, "properties": {"repobilityId": "524e9bf85c389ea3", "scanner": "scanner-primary", "fingerprint": "30e0e7013d398386", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-f24032f250173ffb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/expenses/page.tsx:87"}, "properties": {"repobilityId": "a1de7ae5fc258778", "scanner": "scanner-primary", "fingerprint": "f24032f250173ffb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-932084a315b9e29e", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/clients/page.tsx:18"}, "properties": {"repobilityId": "325bfe57a6b5f4d4", "scanner": "scanner-primary", "fingerprint": "932084a315b9e29e", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-9fa984538a97ad2d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/items/page.tsx:84"}, "properties": {"repobilityId": "4bf60d05c0c475b4", "scanner": "scanner-primary", "fingerprint": "9fa984538a97ad2d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-0abaa4460d3550c4", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/trades/page.tsx:26"}, "properties": {"repobilityId": "b9b02c54e9bcc3be", "scanner": "scanner-primary", "fingerprint": "0abaa4460d3550c4", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-fed83ccba962bf1d", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/worksites/page.tsx:21"}, "properties": {"repobilityId": "5020f203f28c4bf9", "scanner": "scanner-primary", "fingerprint": "fed83ccba962bf1d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-82caf4719f84ea67", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 app/managers/page.tsx:85"}, "properties": {"repobilityId": "cebecf2bc9368b9b", "scanner": "scanner-primary", "fingerprint": "82caf4719f84ea67", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-aafcfefa43aff952", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/receipt-ocr.ts:73"}, "properties": {"repobilityId": "72193ca0dd7a9635", "scanner": "scanner-primary", "fingerprint": "aafcfefa43aff952", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-d7c7bbdb919e7b59", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/manager/mirror.ts:15"}, "properties": {"repobilityId": "49c0b9b2179b7981", "scanner": "scanner-primary", "fingerprint": "d7c7bbdb919e7b59", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-de809baf10f182cc", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/utils/download.ts:13"}, "properties": {"repobilityId": "80a2aa025846790a", "scanner": "scanner-primary", "fingerprint": "de809baf10f182cc", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-8ba5a71e23b15f73", "level": "none", "message": {"text": "Commented-code block (6 lines) in lib/capacitor/tracking.ts:1"}, "properties": {"repobilityId": "65d2edda6b5de666", "scanner": "scanner-primary", "fingerprint": "8ba5a71e23b15f73", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-02bd53274042ad8a", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 lib/capacitor/photo-picker.ts:20"}, "properties": {"repobilityId": "c3e00ca16f3667a3", "scanner": "scanner-primary", "fingerprint": "02bd53274042ad8a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-dab453049c8e70f0", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/audit/format.ts:1"}, "properties": {"repobilityId": "2c07204ad7fcb821", "scanner": "scanner-primary", "fingerprint": "dab453049c8e70f0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-da266b6062007050", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/payroll/calc.ts:1"}, "properties": {"repobilityId": "b0d6a74e897e0f05", "scanner": "scanner-primary", "fingerprint": "da266b6062007050", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2074c1203d5921ce", "level": "none", "message": {"text": "Commented-code block (5 lines) in lib/excel/fill-payroll.ts:103"}, "properties": {"repobilityId": "38b4b4bb34ec5940", "scanner": "scanner-primary", "fingerprint": "2074c1203d5921ce", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}]}]}