{"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-37df4ad9fe0d1163", "name": "Stray `console.log` in TS/JS \u2014 apps/api/scripts/debug-citas.js:24", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/scripts/debug-citas.js:24"}, "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-9356cfb6b8f798c9", "name": "Stray `console.log` in TS/JS \u2014 apps/api/scripts/reparar-cobrado-con-saldo.js:25", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/scripts/reparar-cobrado-con-saldo.js: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-4c97835962634de4", "name": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed.ts:7", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed.ts:7"}, "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-df6767f56ccf4397", "name": "Stray `console.log` in TS/JS \u2014 apps/api/src/main.ts:67", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/main.ts:67"}, "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-9898f949d0bac79b", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/AppShell.tsx:174", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/AppShell.tsx:174"}, "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-f698a4e0ed73f8a1", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/catalogo/DoctorModal.tsx:184", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/catalogo/DoctorModal.tsx:184"}, "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-930a0c0441773752", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/catalogo/CatalogoPage.tsx:193", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/catalogo/CatalogoPage.tsx:193"}, "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-94cf030c5b70d248", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/configuracion/ConfiguracionPage.tsx:307", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/configuracion/ConfiguracionPage.tsx:307"}, "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-69d7e7f8668721fa", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/MetaBreakdown.tsx:17", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/MetaBreakdown.tsx:17"}, "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-2964f9990564b536", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/KpiCards.tsx:22", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/KpiCards.tsx:22"}, "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-7cc961cf30d65609", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/ReportFilters.tsx:106", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/ReportFilters.tsx:106"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-36e6cfcd04e7b834", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/dashboard/DashboardPage.tsx:65", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/dashboard/DashboardPage.tsx:65"}, "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-b7c3269b1467663c", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/landing/LandingPage.tsx:177", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/landing/LandingPage.tsx:177"}, "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-d131e7891fca606d", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaMesGrid.tsx:91", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaMesGrid.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-5c49cbab46fec2f6", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaDiaGrid.tsx:62", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaDiaGrid.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-5c96dde801b1f7e1", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/CitaCard.tsx:133", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/CitaCard.tsx:133"}, "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-87895e56dbfe792b", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaSemanaGrid.tsx:64", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaSemanaGrid.tsx:64"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5edee3eb6e6b3a22", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AtencionModal.tsx:287", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AtencionModal.tsx:287"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b20280fa285869fe", "name": "TODO/FIXME marker in shipping code \u2014 apps/web/src/features/portal/ReservarPage.tsx:16", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 apps/web/src/features/portal/ReservarPage.tsx:16"}, "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-42cc844e5bb8261f", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/pacientes/HistoriaClinicaTimeline.tsx:116", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/pacientes/HistoriaClinicaTimeline.tsx:116"}, "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-2af50b680b77491b", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/mensajes/MensajesPage.tsx:155", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/mensajes/MensajesPage.tsx:155"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-3d642e0e7e45ced3", "name": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/calendario/CalendarioAtencionPage.tsx:220", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/calendario/CalendarioAtencionPage.tsx:220"}, "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-a017ad505e857161", "name": "TODO/FIXME marker in shipping code \u2014 .claude/skills/impeccable/scripts/live-browser.js:6900", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 .claude/skills/impeccable/scripts/live-browser.js:6900"}, "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-1d0c12ce1b5df0ec", "name": "Stray `console.log` in TS/JS \u2014 .claude/skills/impeccable/scripts/live-browser.js:5451", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 .claude/skills/impeccable/scripts/live-browser.js:5451"}, "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-0ffda4dc1278289b", "name": "Stray `console.log` in TS/JS \u2014 .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js:4402", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js:4402"}, "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-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-01d93068ae75d510", "name": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/capturar-ayuda.spec.ts:33", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/capturar-ayuda.spec.ts:33"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-0a461a9160ec70a7", "name": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/ayuda.spec.ts:17", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/ayuda.spec.ts:17"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ecbd76574a9602bc", "name": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/landing.spec.ts:32", "shortDescription": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/landing.spec.ts:32"}, "fullDescription": {"text": "Found a known-risky pattern (local_storage_auth_token). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ee3e044ba18f04bb", "name": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live.mjs:20", "shortDescription": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live.mjs:20"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a6b53970b3759ced", "name": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-poll.mjs:12", "shortDescription": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-poll.mjs:12"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-05e22032dc0c2e74", "name": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/context-signals.mjs:23", "shortDescription": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/context-signals.mjs:23"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-04dbddfdea8db0d9", "name": "Insecure pattern 'direct_innerhtml_assignment' in .claude/skills/impeccable/scripts/live-browser.js:479", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in .claude/skills/impeccable/scripts/live-browser.js:479"}, "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-3a132781ce741413", "name": "Insecure pattern 'domparser_html_parse' in .claude/skills/impeccable/scripts/live-browser.js:4843", "shortDescription": {"text": "Insecure pattern 'domparser_html_parse' in .claude/skills/impeccable/scripts/live-browser.js:4843"}, "fullDescription": {"text": "Found a known-risky pattern (domparser_html_parse). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5ce82a740f9f3098", "name": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-server.mjs:18", "shortDescription": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-server.mjs:18"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-89a930b7578b3a0d", "name": "Insecure pattern 'cors_wildcard' in .claude/skills/impeccable/scripts/live-server.mjs:390", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in .claude/skills/impeccable/scripts/live-server.mjs:390"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-e3fced14e0b53e87", "name": "Insecure pattern 'insert_adjacent_html' in .claude/skills/impeccable/scripts/modern-screenshot.umd.js:7", "shortDescription": {"text": "Insecure pattern 'insert_adjacent_html' in .claude/skills/impeccable/scripts/modern-screenshot.umd.js:7"}, "fullDescription": {"text": "Found a known-risky pattern (insert_adjacent_html). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-1401d560b8055d2c", "name": "Insecure pattern 'direct_outerhtml_assignment' in .claude/skills/impeccable/scripts/live-manual-edit-evidence.mjs:122", "shortDescription": {"text": "Insecure pattern 'direct_outerhtml_assignment' in .claude/skills/impeccable/scripts/live-manual-edit-evidence.mjs:122"}, "fullDescription": {"text": "Found a known-risky pattern (direct_outerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c400952450cf27d7", "name": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-copy-edit-agent.mjs:10", "shortDescription": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-copy-edit-agent.mjs:10"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9bd58f57bc3ef62c", "name": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/lib/is-generated.mjs:16", "shortDescription": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/lib/is-generated.mjs:16"}, "fullDescription": {"text": "Found a known-risky pattern (node_child_process). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-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-604126c8a131e379", "name": "Very large file: .claude/skills/impeccable/scripts/live-browser.js (11086 lines)", "shortDescription": {"text": "Very large file: .claude/skills/impeccable/scripts/live-browser.js (11086 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-c6b7a5cb6c27ed1d", "name": "Very large file: .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js (4903 lines)", "shortDescription": {"text": "Very large file: .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js (4903 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-e65d0e451e5f6ffb", "name": "Very large file: .claude/skills/impeccable/scripts/detector/rules/checks.mjs (2667 lines)", "shortDescription": {"text": "Very large file: .claude/skills/impeccable/scripts/detector/rules/checks.mjs (2667 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-2082f1182baa9c28", "name": "Very large file: .claude/skills/impeccable/scripts/detector/browser/injected/index.mjs (1735 lines)", "shortDescription": {"text": "Very large file: .claude/skills/impeccable/scripts/detector/browser/injected/index.mjs (1735 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 252 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-b06b8d86f24c77f9", "name": "Node manifest has dependencies but no lockfile: apps/api/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4a9eb7dc7c6e3880", "name": "Node manifest has dependencies but no lockfile: apps/web/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-cb3e52667c84fb86", "name": "Node manifest has dependencies but no lockfile: packages/types/package.json", "shortDescription": {"text": "Node manifest has dependencies but no lockfile: packages/types/package.json"}, "fullDescription": {"text": "`package.json` declares dependencies, but no same-directory npm/pnpm/yarn/bun lockfile was found. Generated projects without lockfiles are less reproducible and harder to secure-scan precisely."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 92 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 150 placeholder/mock markers across 33 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, lockfile. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-749d4bc1bd66df5f", "name": "Agent instructions exist but release-hardening basics are missing", "shortDescription": {"text": "Agent instructions exist but release-hardening basics are missing"}, "fullDescription": {"text": "AI-coder instruction files were found, but the repo is missing license, ci, lockfile. Treat this as a contract gap: the agent is guided, but the generated output is not yet guarded by the controls that make it repeatable."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-5a2f8db864e626f8", "name": "Agent authority lacks a verifier contract: .claude/skills/impeccable/reference/hooks.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/impeccable/reference/hooks.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-f6308c6fa82ca5cd", "name": "Agent authority lacks a verifier contract: .claude/skills/impeccable/reference/shape.md", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/impeccable/reference/shape.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-6515e6e86d58d5b3", "name": "Agent authority lacks a verifier contract: .claude/skills/impeccable/scripts/command-metadata.json", "shortDescription": {"text": "Agent authority lacks a verifier contract: .claude/skills/impeccable/scripts/command-metadata.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-a4b5ef8a89299e6d", "name": "Commented-code block (5 lines) in apps/api/src/main.ts:38", "shortDescription": {"text": "Commented-code block (5 lines) in apps/api/src/main.ts:38"}, "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-6794e6dd7b9a73ab", "name": "Commented-code block (5 lines) in apps/web/public/sw-push.js:2", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/public/sw-push.js:2"}, "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-75c217f91033b6fb", "name": "Commented-code block (5 lines) in apps/web/src/lib/utils.ts:28", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/lib/utils.ts:28"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-45e3bc5674f56d6f", "name": "Commented-code block (5 lines) in apps/web/src/features/landing/LandingPage.tsx:7", "shortDescription": {"text": "Commented-code block (5 lines) in apps/web/src/features/landing/LandingPage.tsx:7"}, "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-7ed713518e64d130", "name": "Commented-code block (6 lines) in .claude/skills/impeccable/scripts/hook-lib.mjs:937", "shortDescription": {"text": "Commented-code block (6 lines) in .claude/skills/impeccable/scripts/hook-lib.mjs:937"}, "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-1baeff73dee89192", "name": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/live-poll.mjs:18", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/live-poll.mjs: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-becb02117e6c70ac", "name": "Legacy-named symbol `withoutOld` in .claude/skills/impeccable/scripts/live-inject.mjs:160", "shortDescription": {"text": "Legacy-named symbol `withoutOld` in .claude/skills/impeccable/scripts/live-inject.mjs:160"}, "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-59b725839b001371", "name": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/live-inject.mjs:406", "shortDescription": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/live-inject.mjs:406"}, "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-065289db7780ebf9", "name": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/live-browser.js:33", "shortDescription": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/live-browser.js:33"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-320a976c097f6373", "name": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/live-browser.js:5519", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/live-browser.js:5519"}, "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-2bd2ef47647b33b2", "name": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/live-wrap.mjs:202", "shortDescription": {"text": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/live-wrap.mjs:202"}, "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-05e243f0463fcf14", "name": "Commented-code block (11 lines) in .claude/skills/impeccable/scripts/live-server.mjs:537", "shortDescription": {"text": "Commented-code block (11 lines) in .claude/skills/impeccable/scripts/live-server.mjs:537"}, "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-b16d90ab0270fff8", "name": "Legacy-named symbol `singleOld` in .claude/skills/impeccable/scripts/hook-before-edit.mjs:115", "shortDescription": {"text": "Legacy-named symbol `singleOld` in .claude/skills/impeccable/scripts/hook-before-edit.mjs:115"}, "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-1a30b7179eb597df", "name": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/modern-screenshot.umd.js:7", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/modern-screenshot.umd.js:7"}, "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-626ea324dec57349", "name": "Legacy-named symbol `source_shadow_preview_deprecated` in .claude/skills/impeccable/scripts/live-accept.mjs:131", "shortDescription": {"text": "Legacy-named symbol `source_shadow_preview_deprecated` in .claude/skills/impeccable/scripts/live-accept.mjs:131"}, "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-054d870261600733", "name": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/live-accept.mjs:469", "shortDescription": {"text": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/live-accept.mjs:469"}, "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-62220a9221f417e2", "name": "Commented-code block (6 lines) in .claude/skills/impeccable/scripts/palette.mjs:441", "shortDescription": {"text": "Commented-code block (6 lines) in .claude/skills/impeccable/scripts/palette.mjs:441"}, "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-a5453a5c2c1974e4", "name": "Legacy-named symbol `contextLegacy` in .claude/skills/impeccable/scripts/lib/impeccable-paths.mjs:21", "shortDescription": {"text": "Legacy-named symbol `contextLegacy` in .claude/skills/impeccable/scripts/lib/impeccable-paths.mjs:21"}, "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-8dd326e9c5123b62", "name": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/lib/design-parser.mjs:39", "shortDescription": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/lib/design-parser.mjs:39"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-a472357a5f1f52f0", "name": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js:25", "shortDescription": {"text": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js:25"}, "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-3dd90d0398203834", "name": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs:22", "shortDescription": {"text": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs:22"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b047195ee1d8a966", "name": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs:195", "shortDescription": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs:195"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-65d146684aff3721", "name": "Commented-code block (10 lines) in .claude/skills/impeccable/scripts/detector/rules/checks.mjs:102", "shortDescription": {"text": "Commented-code block (10 lines) in .claude/skills/impeccable/scripts/detector/rules/checks.mjs: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-243e862c2143f77a", "name": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/detector/shared/constants.mjs:11", "shortDescription": {"text": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/detector/shared/constants.mjs:11"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-108daeee872ff4de", "name": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/detector/browser/injected/index.mjs:17", "shortDescription": {"text": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/detector/browser/injected/index.mjs:17"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-9996447513897762", "name": "30 env vars used in code but missing from .env.example", "shortDescription": {"text": "30 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `CAPTURAS`, `CI`, `CURSOR_PROJECT_DIR`, `HOME`, `IMPECCABLE_CONTEXT_DIR`, `IMPECCABLE_CRITIQUE_META`, `IMPECCABLE_HOOK_DEBUG`, `IMPECCABLE_HOOK_DEPTH` + 22 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6040577660fa76aa", "name": "Frontend route `/reservar/:slug` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/reservar/:slug` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cf35c84928e91a15", "name": "Frontend route `/qr/:slug` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/qr/:slug` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-58e0386a3a620b1d", "name": "Frontend route `/establecer-password` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `/establecer-password` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-795de5228a4485d7", "name": "Frontend route `inicio` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `inicio` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9c94f996e0376bf2", "name": "Frontend route `agenda` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `agenda` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-29da29987fca33e1", "name": "Frontend route `calendario-atencion` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `calendario-atencion` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-839d0116e801ede0", "name": "Frontend route `pacientes` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `pacientes` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-09d3c380bb76d303", "name": "Frontend route `pacientes/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `pacientes/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-cfb1be852696b32f", "name": "Frontend route `caja` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `caja` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-23ecc90eda59d9d9", "name": "Frontend route `gastos` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `gastos` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-56b3df96a61ea157", "name": "Frontend route `deudores` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `deudores` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3fca1e76ab4cfa73", "name": "Frontend route `mensajes` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `mensajes` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-3a2128addff6582a", "name": "Frontend route `catalogo` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `catalogo` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5f54d38a2ff14d17", "name": "Frontend route `ayuda` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `ayuda` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-432d09ad9097c807", "name": "Frontend route `configuracion` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `configuracion` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-d44750b1514936cd", "name": "Frontend route `reportes` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `reportes` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-bdc0995d335401df", "name": "Frontend route `actividad` has no Link/navigate to it \u2014 apps/web/src/App.tsx", "shortDescription": {"text": "Frontend route `actividad` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "fullDescription": {"text": "The route is registered but no `<Link to=\u2026>` or `navigate(\u2026)` in the codebase navigates here. Either it's reachable only via direct URL (intentional), it's dead, or the link broke during a refactor."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-44ef15bf59b340c7", "name": "Dangling fetch: POST http://localhost:${info.port}/poll (.claude/skills/impeccable/scripts/live-complete.mjs:60)", "shortDescription": {"text": "Dangling fetch: POST http://localhost:${info.port}/poll (.claude/skills/impeccable/scripts/live-complete.mjs:60)"}, "fullDescription": {"text": "`.claude/skills/impeccable/scripts/live-complete.mjs:60` calls `POST http://localhost:${info.port}/poll` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:/<p>/poll`\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-115c79099f481498", "name": "Dangling fetch: GET http://localhost:${info.port}/status?token=${info.token} (.claude/skills/impeccable/scripts/live-sta", "shortDescription": {"text": "Dangling fetch: GET http://localhost:${info.port}/status?token=${info.token} (.claude/skills/impeccable/scripts/live-status.mjs:17)"}, "fullDescription": {"text": "`.claude/skills/impeccable/scripts/live-status.mjs:17` calls `GET http://localhost:${info.port}/status?token=${info.token}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:/<p>/status`\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-417d4143678da048", "name": "Dangling fetch: GET http://localhost:${PORT}/design-system.json?token=${TOKEN} (.claude/skills/impeccable/scripts/live-b", "shortDescription": {"text": "Dangling fetch: GET http://localhost:${PORT}/design-system.json?token=${TOKEN} (.claude/skills/impeccable/scripts/live-browser.js:10352)"}, "fullDescription": {"text": "`.claude/skills/impeccable/scripts/live-browser.js:10352` calls `GET http://localhost:${PORT}/design-system.json?token=${TOKEN}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:/<p>/design-system.json`\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-967238b8ed655f16", "name": "Dangling fetch: GET http://localhost:${PORT}/design-system/raw?token=${TOKEN} (.claude/skills/impeccable/scripts/live-br", "shortDescription": {"text": "Dangling fetch: GET http://localhost:${PORT}/design-system/raw?token=${TOKEN} (.claude/skills/impeccable/scripts/live-browser.js:10353)"}, "fullDescription": {"text": "`.claude/skills/impeccable/scripts/live-browser.js:10353` calls `GET http://localhost:${PORT}/design-system/raw?token=${TOKEN}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:/<p>/design-system/raw`\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-29271db79288bf1f", "name": "Dangling fetch: GET http://localhost:${info.port}/stop?token=${info.token} (.claude/skills/impeccable/scripts/live-serve", "shortDescription": {"text": "Dangling fetch: GET http://localhost:${info.port}/stop?token=${info.token} (.claude/skills/impeccable/scripts/live-server.mjs:1026)"}, "fullDescription": {"text": "`.claude/skills/impeccable/scripts/live-server.mjs:1026` calls `GET http://localhost:${info.port}/stop?token=${info.token}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:/<p>/stop`\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-343160e8bd29b592", "name": "Dangling fetch: GET http://localhost:${port}/ (.claude/skills/impeccable/scripts/detector/node/file-system.mjs:162)", "shortDescription": {"text": "Dangling fetch: GET http://localhost:${port}/ (.claude/skills/impeccable/scripts/detector/node/file-system.mjs:162)"}, "fullDescription": {"text": "`.claude/skills/impeccable/scripts/detector/node/file-system.mjs:162` calls `GET http://localhost:${port}/` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/http:/localhost:/<p>`\nIf this points at an external API, prefix it with `https://` so the matcher skips it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "high", "confidence": 1.0}}, {"id": "scanner-8292c0931391749a", "name": "Unused endpoint: POST /auth/register", "shortDescription": {"text": "Unused endpoint: POST /auth/register"}, "fullDescription": {"text": "`apps/api/src/auth/auth.controller.ts` declares `POST /auth/register` 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-8fdbacfe9430a6ed", "name": "Unused endpoint: POST /auth/login", "shortDescription": {"text": "Unused endpoint: POST /auth/login"}, "fullDescription": {"text": "`apps/api/src/auth/auth.controller.ts` declares `POST /auth/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-b36892106ecdc9aa", "name": "Unused endpoint: POST /auth/refresh", "shortDescription": {"text": "Unused endpoint: POST /auth/refresh"}, "fullDescription": {"text": "`apps/api/src/auth/auth.controller.ts` declares `POST /auth/refresh` 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-cdd0498f1a6e6340", "name": "Unused endpoint: POST /auth/google", "shortDescription": {"text": "Unused endpoint: POST /auth/google"}, "fullDescription": {"text": "`apps/api/src/auth/auth.controller.ts` declares `POST /auth/google` 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-56208bd3b26f952a", "name": "Unused endpoint: POST /auth/password/solicitar", "shortDescription": {"text": "Unused endpoint: POST /auth/password/solicitar"}, "fullDescription": {"text": "`apps/api/src/auth/auth.controller.ts` declares `POST /auth/password/solicitar` 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-92232271fe10cec3", "name": "Unused endpoint: POST /auth/password/establecer", "shortDescription": {"text": "Unused endpoint: POST /auth/password/establecer"}, "fullDescription": {"text": "`apps/api/src/auth/auth.controller.ts` declares `POST /auth/password/establecer` 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-7965ee75aa173d71", "name": "Unused endpoint: DELETE /plantillas-horario/:id", "shortDescription": {"text": "Unused endpoint: DELETE /plantillas-horario/:id"}, "fullDescription": {"text": "`apps/api/src/modules/plantillas/plantillas.controller.ts` declares `DELETE /plantillas-horario/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-410f8d9c84329ada", "name": "Unused endpoint: GET /gastos/resumen", "shortDescription": {"text": "Unused endpoint: GET /gastos/resumen"}, "fullDescription": {"text": "`apps/api/src/modules/gastos/gastos.controller.ts` declares `GET /gastos/resumen` 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-34e455e7edb4a920", "name": "Unused endpoint: PUT /gastos/:id", "shortDescription": {"text": "Unused endpoint: PUT /gastos/:id"}, "fullDescription": {"text": "`apps/api/src/modules/gastos/gastos.controller.ts` declares `PUT /gastos/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2e6aaec60d8220f7", "name": "Unused endpoint: DELETE /gastos/:id", "shortDescription": {"text": "Unused endpoint: DELETE /gastos/:id"}, "fullDescription": {"text": "`apps/api/src/modules/gastos/gastos.controller.ts` declares `DELETE /gastos/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f4af7d7c4b5873c6", "name": "Unused endpoint: GET /caja/hoy", "shortDescription": {"text": "Unused endpoint: GET /caja/hoy"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `GET /caja/hoy` 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-0532506c85091be2", "name": "Unused endpoint: GET /caja/estado", "shortDescription": {"text": "Unused endpoint: GET /caja/estado"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `GET /caja/estado` 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-9bd6c041033fb1c3", "name": "Unused endpoint: POST /caja/abrir", "shortDescription": {"text": "Unused endpoint: POST /caja/abrir"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `POST /caja/abrir` 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-c922ce0e95da1e35", "name": "Unused endpoint: POST /caja/cerrar", "shortDescription": {"text": "Unused endpoint: POST /caja/cerrar"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `POST /caja/cerrar` 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-af2b533cc152c188", "name": "Unused endpoint: POST /caja/reabrir", "shortDescription": {"text": "Unused endpoint: POST /caja/reabrir"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `POST /caja/reabrir` 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-a77fe5432c3f6b54", "name": "Unused endpoint: PUT /caja/:id/revisar", "shortDescription": {"text": "Unused endpoint: PUT /caja/:id/revisar"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `PUT /caja/:id/revisar` 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-4f46833e10874e4c", "name": "Unused endpoint: GET /caja/historial", "shortDescription": {"text": "Unused endpoint: GET /caja/historial"}, "fullDescription": {"text": "`apps/api/src/modules/caja/caja.controller.ts` declares `GET /caja/historial` 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-24d2cba95660b409", "name": "Unused endpoint: GET /reportes/mensual", "shortDescription": {"text": "Unused endpoint: GET /reportes/mensual"}, "fullDescription": {"text": "`apps/api/src/modules/reportes/reportes.controller.ts` declares `GET /reportes/mensual` 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-d21d1627d3e4675e", "name": "Unused endpoint: GET /reportes/citas", "shortDescription": {"text": "Unused endpoint: GET /reportes/citas"}, "fullDescription": {"text": "`apps/api/src/modules/reportes/reportes.controller.ts` declares `GET /reportes/citas` 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-2550c1ea62a5b7b7", "name": "Unused endpoint: GET /reportes/cobranzas", "shortDescription": {"text": "Unused endpoint: GET /reportes/cobranzas"}, "fullDescription": {"text": "`apps/api/src/modules/reportes/reportes.controller.ts` declares `GET /reportes/cobranzas` 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-259073849467fbf2", "name": "Unused endpoint: GET /reportes/gastos", "shortDescription": {"text": "Unused endpoint: GET /reportes/gastos"}, "fullDescription": {"text": "`apps/api/src/modules/reportes/reportes.controller.ts` declares `GET /reportes/gastos` 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-091f0eada74f98cc", "name": "Unused endpoint: GET /reportes/pacientes", "shortDescription": {"text": "Unused endpoint: GET /reportes/pacientes"}, "fullDescription": {"text": "`apps/api/src/modules/reportes/reportes.controller.ts` declares `GET /reportes/pacientes` 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-d3de90324828b515", "name": "Unused endpoint: GET /reportes/servicios", "shortDescription": {"text": "Unused endpoint: GET /reportes/servicios"}, "fullDescription": {"text": "`apps/api/src/modules/reportes/reportes.controller.ts` declares `GET /reportes/servicios` 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-893781598880eb54", "name": "Unused endpoint: PUT /disponibilidades/:id", "shortDescription": {"text": "Unused endpoint: PUT /disponibilidades/:id"}, "fullDescription": {"text": "`apps/api/src/modules/disponibilidades/disponibilidades.controller.ts` declares `PUT /disponibilidades/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-261a2b843e78f312", "name": "Unused endpoint: DELETE /disponibilidades/:id", "shortDescription": {"text": "Unused endpoint: DELETE /disponibilidades/:id"}, "fullDescription": {"text": "`apps/api/src/modules/disponibilidades/disponibilidades.controller.ts` declares `DELETE /disponibilidades/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3266ae2a89363c04", "name": "Unused endpoint: GET /atenciones/paciente/:pacienteId", "shortDescription": {"text": "Unused endpoint: GET /atenciones/paciente/:pacienteId"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `GET /atenciones/paciente/:pacienteId` 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-1d1af6b0eb827e98", "name": "Unused endpoint: GET /atenciones/cita/:citaId", "shortDescription": {"text": "Unused endpoint: GET /atenciones/cita/:citaId"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `GET /atenciones/cita/:citaId` 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-2a57e10bde63522d", "name": "Unused endpoint: PUT /atenciones/cita/:citaId", "shortDescription": {"text": "Unused endpoint: PUT /atenciones/cita/:citaId"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `PUT /atenciones/cita/:citaId` 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-025d80655efaaeaa", "name": "Unused endpoint: POST /atenciones/cita/:citaId/adjuntos", "shortDescription": {"text": "Unused endpoint: POST /atenciones/cita/:citaId/adjuntos"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `POST /atenciones/cita/:citaId/adjuntos` 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-be00e007110eca00", "name": "Unused endpoint: GET /atenciones/cita/:citaId/adjuntos/:indice", "shortDescription": {"text": "Unused endpoint: GET /atenciones/cita/:citaId/adjuntos/:indice"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `GET /atenciones/cita/:citaId/adjuntos/:indice` 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-7611bbdbea3802f8", "name": "Unused endpoint: DELETE /atenciones/cita/:citaId/adjuntos/:indice", "shortDescription": {"text": "Unused endpoint: DELETE /atenciones/cita/:citaId/adjuntos/:indice"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `DELETE /atenciones/cita/:citaId/adjuntos/:indice` 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-13f9db208b9b2b71", "name": "Unused endpoint: POST /atenciones/cita/:citaId/recetas", "shortDescription": {"text": "Unused endpoint: POST /atenciones/cita/:citaId/recetas"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `POST /atenciones/cita/:citaId/recetas` 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-831c3183d234a6e5", "name": "Unused endpoint: GET /atenciones/cita/:citaId/recetas", "shortDescription": {"text": "Unused endpoint: GET /atenciones/cita/:citaId/recetas"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `GET /atenciones/cita/:citaId/recetas` 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-06051e0d56b8db6c", "name": "Unused endpoint: GET /atenciones/recetas/:id/pdf", "shortDescription": {"text": "Unused endpoint: GET /atenciones/recetas/:id/pdf"}, "fullDescription": {"text": "`apps/api/src/modules/atenciones/atenciones.controller.ts` declares `GET /atenciones/recetas/:id/pdf` 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-f97c937bda4116a8", "name": "Unused endpoint: PUT /servicios/:id", "shortDescription": {"text": "Unused endpoint: PUT /servicios/:id"}, "fullDescription": {"text": "`apps/api/src/modules/servicios/servicios.controller.ts` declares `PUT /servicios/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4f82a20ee467727f", "name": "Unused endpoint: DELETE /servicios/:id", "shortDescription": {"text": "Unused endpoint: DELETE /servicios/:id"}, "fullDescription": {"text": "`apps/api/src/modules/servicios/servicios.controller.ts` declares `DELETE /servicios/:id` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b0b5c9066f76f11d", "name": "Unused endpoint: GET /public/:slug", "shortDescription": {"text": "Unused endpoint: GET /public/:slug"}, "fullDescription": {"text": "`apps/api/src/modules/portal/portal.controller.ts` declares `GET /public/:slug` 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-3055d5fce6fc29ee", "name": "Unused endpoint: GET /public/:slug/prefill/:token", "shortDescription": {"text": "Unused endpoint: GET /public/:slug/prefill/:token"}, "fullDescription": {"text": "`apps/api/src/modules/portal/portal.controller.ts` declares `GET /public/:slug/prefill/:token` but no frontend code we scanned calls it. This is fine if the endpoint serves external clients (mobile app, third-party, server-side webhooks). Otherwise it's dead code \u2014 consider removing or documenting who consumes it."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6add6d6c993322d4", "name": "Unused endpoint: GET /public/:slug/qr", "shortDescription": {"text": "Unused endpoint: GET /public/:slug/qr"}, "fullDescription": {"text": "`apps/api/src/modules/portal/portal.controller.ts` declares `GET /public/:slug/qr` 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-3ea581f819a66a2a", "name": "Unused endpoint: GET /public/:slug/dias", "shortDescription": {"text": "Unused endpoint: GET /public/:slug/dias"}, "fullDescription": {"text": "`apps/api/src/modules/portal/portal.controller.ts` declares `GET /public/:slug/dias` 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-7c5e89223674d461", "name": "Unused endpoint: GET /public/:slug/slots", "shortDescription": {"text": "Unused endpoint: GET /public/:slug/slots"}, "fullDescription": {"text": "`apps/api/src/modules/portal/portal.controller.ts` declares `GET /public/:slug/slots` 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-c1c91f1ecfd6fb0b", "name": "Unused endpoint: POST /public/:slug/reservas", "shortDescription": {"text": "Unused endpoint: POST /public/:slug/reservas"}, "fullDescription": {"text": "`apps/api/src/modules/portal/portal.controller.ts` declares `POST /public/:slug/reservas` 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-93b40a8e3c787345", "name": "Unused endpoint: GET /cobros/deudores", "shortDescription": {"text": "Unused endpoint: GET /cobros/deudores"}, "fullDescription": {"text": "`apps/api/src/modules/cobros/cobros.controller.ts` declares `GET /cobros/deudores` 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-26c1a7aaffbde143", "name": "Unused endpoint: GET /cobros/deudores/resumen", "shortDescription": {"text": "Unused endpoint: GET /cobros/deudores/resumen"}, "fullDescription": {"text": "`apps/api/src/modules/cobros/cobros.controller.ts` declares `GET /cobros/deudores/resumen` 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-7c63c674d2172411", "name": "Unused endpoint: GET /cobros/cita/:citaId", "shortDescription": {"text": "Unused endpoint: GET /cobros/cita/:citaId"}, "fullDescription": {"text": "`apps/api/src/modules/cobros/cobros.controller.ts` declares `GET /cobros/cita/:citaId` 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-f03f07b9e18c3235", "name": "Unused endpoint: PUT /cobros/:id/total", "shortDescription": {"text": "Unused endpoint: PUT /cobros/:id/total"}, "fullDescription": {"text": "`apps/api/src/modules/cobros/cobros.controller.ts` declares `PUT /cobros/:id/total` 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-12fff7c6919581bf", "name": "Unused endpoint: POST /cobros/:id/pagos", "shortDescription": {"text": "Unused endpoint: POST /cobros/:id/pagos"}, "fullDescription": {"text": "`apps/api/src/modules/cobros/cobros.controller.ts` declares `POST /cobros/:id/pagos` 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-8e901a6f0b225c61", "name": "Unused endpoint: POST /cobros/pagos/:id/anular", "shortDescription": {"text": "Unused endpoint: POST /cobros/pagos/:id/anular"}, "fullDescription": {"text": "`apps/api/src/modules/cobros/cobros.controller.ts` declares `POST /cobros/pagos/:id/anular` 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-4f06149119e5d737", "name": "Unused endpoint: POST /citas/no-shows/procesar", "shortDescription": {"text": "Unused endpoint: POST /citas/no-shows/procesar"}, "fullDescription": {"text": "`apps/api/src/modules/citas/citas.controller.ts` declares `POST /citas/no-shows/procesar` 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-bd8d1c52fc670927", "name": "Unused endpoint: PUT /citas/:id/estado", "shortDescription": {"text": "Unused endpoint: PUT /citas/:id/estado"}, "fullDescription": {"text": "`apps/api/src/modules/citas/citas.controller.ts` declares `PUT /citas/:id/estado` 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/19977"}, "properties": {"repository": "soljancic/pos-consultorio", "repoUrl": "https://github.com/soljancic/pos-consultorio", "branch": "main"}, "results": [{"ruleId": "scanner-37df4ad9fe0d1163", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/scripts/debug-citas.js:24"}, "properties": {"repobilityId": "424978545cc2aef6", "scanner": "scanner-primary", "fingerprint": "37df4ad9fe0d1163", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9356cfb6b8f798c9", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/scripts/reparar-cobrado-con-saldo.js:25"}, "properties": {"repobilityId": "b092272077cf2bc9", "scanner": "scanner-primary", "fingerprint": "9356cfb6b8f798c9", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4c97835962634de4", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/prisma/seed.ts:7"}, "properties": {"repobilityId": "af65da84a66d15d9", "scanner": "scanner-primary", "fingerprint": "4c97835962634de4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-df6767f56ccf4397", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 apps/api/src/main.ts:67"}, "properties": {"repobilityId": "1df3dab31f34a60f", "scanner": "scanner-primary", "fingerprint": "df6767f56ccf4397", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-9898f949d0bac79b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/components/shared/AppShell.tsx:174"}, "properties": {"repobilityId": "00296ce5ad6fdada", "scanner": "scanner-primary", "fingerprint": "9898f949d0bac79b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-f698a4e0ed73f8a1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/catalogo/DoctorModal.tsx:184"}, "properties": {"repobilityId": "5d71bdc5e4571451", "scanner": "scanner-primary", "fingerprint": "f698a4e0ed73f8a1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-930a0c0441773752", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/catalogo/CatalogoPage.tsx:193"}, "properties": {"repobilityId": "0452dc5c1e02b775", "scanner": "scanner-primary", "fingerprint": "930a0c0441773752", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-94cf030c5b70d248", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/configuracion/ConfiguracionPage.tsx:307"}, "properties": {"repobilityId": "973c9827c0508fc0", "scanner": "scanner-primary", "fingerprint": "94cf030c5b70d248", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-69d7e7f8668721fa", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/MetaBreakdown.tsx:17"}, "properties": {"repobilityId": "a82f0311549b5b4b", "scanner": "scanner-primary", "fingerprint": "69d7e7f8668721fa", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2964f9990564b536", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/KpiCards.tsx:22"}, "properties": {"repobilityId": "a82e7726d0ecd681", "scanner": "scanner-primary", "fingerprint": "2964f9990564b536", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7cc961cf30d65609", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/reportes/components/ReportFilters.tsx:106"}, "properties": {"repobilityId": "4a351586bb36396a", "scanner": "scanner-primary", "fingerprint": "7cc961cf30d65609", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-36e6cfcd04e7b834", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/dashboard/DashboardPage.tsx:65"}, "properties": {"repobilityId": "a21d1a1bae4cfa0f", "scanner": "scanner-primary", "fingerprint": "36e6cfcd04e7b834", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b7c3269b1467663c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/landing/LandingPage.tsx:177"}, "properties": {"repobilityId": "b3fdd8585e2a80fb", "scanner": "scanner-primary", "fingerprint": "b7c3269b1467663c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d131e7891fca606d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaMesGrid.tsx:91"}, "properties": {"repobilityId": "a04577b66a3a53d4", "scanner": "scanner-primary", "fingerprint": "d131e7891fca606d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5c49cbab46fec2f6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaDiaGrid.tsx:62"}, "properties": {"repobilityId": "d9fff78c5f4e0656", "scanner": "scanner-primary", "fingerprint": "5c49cbab46fec2f6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5c96dde801b1f7e1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/CitaCard.tsx:133"}, "properties": {"repobilityId": "a70c1906910657e1", "scanner": "scanner-primary", "fingerprint": "5c96dde801b1f7e1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-87895e56dbfe792b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AgendaSemanaGrid.tsx:64"}, "properties": {"repobilityId": "1be00ed90b418620", "scanner": "scanner-primary", "fingerprint": "87895e56dbfe792b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-5edee3eb6e6b3a22", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/agenda/AtencionModal.tsx:287"}, "properties": {"repobilityId": "f9b278c7fda84705", "scanner": "scanner-primary", "fingerprint": "5edee3eb6e6b3a22", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b20280fa285869fe", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 apps/web/src/features/portal/ReservarPage.tsx:16"}, "properties": {"repobilityId": "68047b58d6631e82", "scanner": "scanner-primary", "fingerprint": "b20280fa285869fe", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-42cc844e5bb8261f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/pacientes/HistoriaClinicaTimeline.tsx:116"}, "properties": {"repobilityId": "67655d7552b694fc", "scanner": "scanner-primary", "fingerprint": "42cc844e5bb8261f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2af50b680b77491b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/mensajes/MensajesPage.tsx:155"}, "properties": {"repobilityId": "98bfd825222e5e25", "scanner": "scanner-primary", "fingerprint": "2af50b680b77491b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3d642e0e7e45ced3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 apps/web/src/features/calendario/CalendarioAtencionPage.tsx:220"}, "properties": {"repobilityId": "0e2397c9b96d1be5", "scanner": "scanner-primary", "fingerprint": "3d642e0e7e45ced3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a017ad505e857161", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 .claude/skills/impeccable/scripts/live-browser.js:6900"}, "properties": {"repobilityId": "9649f9b814714dd7", "scanner": "scanner-primary", "fingerprint": "a017ad505e857161", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-1d0c12ce1b5df0ec", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 .claude/skills/impeccable/scripts/live-browser.js:5451"}, "properties": {"repobilityId": "01ffae13be8e53b4", "scanner": "scanner-primary", "fingerprint": "1d0c12ce1b5df0ec", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-0ffda4dc1278289b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js:4402"}, "properties": {"repobilityId": "da2b23395e443e34", "scanner": "scanner-primary", "fingerprint": "0ffda4dc1278289b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"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-01d93068ae75d510", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/capturar-ayuda.spec.ts:33"}, "properties": {"repobilityId": "965ae339e9f08ea7", "scanner": "scanner-primary", "fingerprint": "01d93068ae75d510", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/e2e/capturar-ayuda.spec.ts"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-0a461a9160ec70a7", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/ayuda.spec.ts:17"}, "properties": {"repobilityId": "564d0aea20d96f70", "scanner": "scanner-primary", "fingerprint": "0a461a9160ec70a7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/e2e/ayuda.spec.ts"}, "region": {"startLine": 17}}}]}, {"ruleId": "scanner-ecbd76574a9602bc", "level": "warning", "message": {"text": "Insecure pattern 'local_storage_auth_token' in apps/web/e2e/landing.spec.ts:32"}, "properties": {"repobilityId": "65dba0c195603846", "scanner": "scanner-primary", "fingerprint": "ecbd76574a9602bc", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "local_storage_auth_token"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/e2e/landing.spec.ts"}, "region": {"startLine": 32}}}]}, {"ruleId": "scanner-ee3e044ba18f04bb", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live.mjs:20"}, "properties": {"repobilityId": "e327fdc2ee6e1304", "scanner": "scanner-primary", "fingerprint": "ee3e044ba18f04bb", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live.mjs"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-a6b53970b3759ced", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-poll.mjs:12"}, "properties": {"repobilityId": "227f9ce57836ef88", "scanner": "scanner-primary", "fingerprint": "a6b53970b3759ced", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-poll.mjs"}, "region": {"startLine": 12}}}]}, {"ruleId": "scanner-05e22032dc0c2e74", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/context-signals.mjs:23"}, "properties": {"repobilityId": "f207dc045f04d4fb", "scanner": "scanner-primary", "fingerprint": "05e22032dc0c2e74", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/context-signals.mjs"}, "region": {"startLine": 23}}}]}, {"ruleId": "scanner-04dbddfdea8db0d9", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in .claude/skills/impeccable/scripts/live-browser.js:479"}, "properties": {"repobilityId": "a385fe1ff803370e", "scanner": "scanner-primary", "fingerprint": "04dbddfdea8db0d9", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-browser.js"}, "region": {"startLine": 479}}}]}, {"ruleId": "scanner-3a132781ce741413", "level": "warning", "message": {"text": "Insecure pattern 'domparser_html_parse' in .claude/skills/impeccable/scripts/live-browser.js:4843"}, "properties": {"repobilityId": "22a9b987421218b0", "scanner": "scanner-primary", "fingerprint": "3a132781ce741413", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "domparser_html_parse"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-browser.js"}, "region": {"startLine": 4843}}}]}, {"ruleId": "scanner-5ce82a740f9f3098", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-server.mjs:18"}, "properties": {"repobilityId": "ebfd6f8477058b09", "scanner": "scanner-primary", "fingerprint": "5ce82a740f9f3098", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-server.mjs"}, "region": {"startLine": 18}}}]}, {"ruleId": "scanner-89a930b7578b3a0d", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in .claude/skills/impeccable/scripts/live-server.mjs:390"}, "properties": {"repobilityId": "49d2b7660062be31", "scanner": "scanner-primary", "fingerprint": "89a930b7578b3a0d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-server.mjs"}, "region": {"startLine": 390}}}]}, {"ruleId": "scanner-e3fced14e0b53e87", "level": "warning", "message": {"text": "Insecure pattern 'insert_adjacent_html' in .claude/skills/impeccable/scripts/modern-screenshot.umd.js:7"}, "properties": {"repobilityId": "12f57c8200874ad2", "scanner": "scanner-primary", "fingerprint": "e3fced14e0b53e87", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "insert_adjacent_html"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/modern-screenshot.umd.js"}, "region": {"startLine": 7}}}]}, {"ruleId": "scanner-1401d560b8055d2c", "level": "warning", "message": {"text": "Insecure pattern 'direct_outerhtml_assignment' in .claude/skills/impeccable/scripts/live-manual-edit-evidence.mjs:122"}, "properties": {"repobilityId": "76e2c85cff790607", "scanner": "scanner-primary", "fingerprint": "1401d560b8055d2c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_outerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-manual-edit-evidence.mjs"}, "region": {"startLine": 122}}}]}, {"ruleId": "scanner-c400952450cf27d7", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/live-copy-edit-agent.mjs:10"}, "properties": {"repobilityId": "43516cfa54eb2417", "scanner": "scanner-primary", "fingerprint": "c400952450cf27d7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/live-copy-edit-agent.mjs"}, "region": {"startLine": 10}}}]}, {"ruleId": "scanner-9bd58f57bc3ef62c", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in .claude/skills/impeccable/scripts/lib/is-generated.mjs:16"}, "properties": {"repobilityId": "eeab4fa2f745d5ef", "scanner": "scanner-primary", "fingerprint": "9bd58f57bc3ef62c", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/lib/is-generated.mjs"}, "region": {"startLine": 16}}}]}, {"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-604126c8a131e379", "level": "note", "message": {"text": "Very large file: .claude/skills/impeccable/scripts/live-browser.js (11086 lines)"}, "properties": {"repobilityId": "b994180f29d9c51e", "scanner": "scanner-primary", "fingerprint": "604126c8a131e379", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-c6b7a5cb6c27ed1d", "level": "note", "message": {"text": "Very large file: .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js (4903 lines)"}, "properties": {"repobilityId": "37392e6b9af9fc0d", "scanner": "scanner-primary", "fingerprint": "c6b7a5cb6c27ed1d", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-e65d0e451e5f6ffb", "level": "note", "message": {"text": "Very large file: .claude/skills/impeccable/scripts/detector/rules/checks.mjs (2667 lines)"}, "properties": {"repobilityId": "4c47e38799d72f96", "scanner": "scanner-primary", "fingerprint": "e65d0e451e5f6ffb", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-2082f1182baa9c28", "level": "note", "message": {"text": "Very large file: .claude/skills/impeccable/scripts/detector/browser/injected/index.mjs (1735 lines)"}, "properties": {"repobilityId": "1df2cd1bf3120f8f", "scanner": "scanner-primary", "fingerprint": "2082f1182baa9c28", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "6da8e556790bcbde", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b06b8d86f24c77f9", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/api/package.json"}, "properties": {"repobilityId": "ce77cd34ed0306d4", "scanner": "scanner-primary", "fingerprint": "b06b8d86f24c77f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-4a9eb7dc7c6e3880", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: apps/web/package.json"}, "properties": {"repobilityId": "6c1704bf24cf19ac", "scanner": "scanner-primary", "fingerprint": "4a9eb7dc7c6e3880", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-cb3e52667c84fb86", "level": "note", "message": {"text": "Node manifest has dependencies but no lockfile: packages/types/package.json"}, "properties": {"repobilityId": "b5e2784f829944e6", "scanner": "scanner-primary", "fingerprint": "cb3e52667c84fb86", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["dependency", "lockfile", "reproducibility", "generated-repo-pattern"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/types/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "330e22c9ff4c2ac2", "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": "070f756dc7884e28", "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": "1edf795dcb5c7f1f", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "fbf112261e9f3d43", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-749d4bc1bd66df5f", "level": "warning", "message": {"text": "Agent instructions exist but release-hardening basics are missing"}, "properties": {"repobilityId": "e899ac29f14918b3", "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": "be0e929427ef8d01", "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": "c9c7f2b7c1c295ba", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-5a2f8db864e626f8", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/impeccable/reference/hooks.md"}, "properties": {"repobilityId": "e2f116c2980dd5c8", "scanner": "scanner-primary", "fingerprint": "5a2f8db864e626f8", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/reference/hooks.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f6308c6fa82ca5cd", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/impeccable/reference/shape.md"}, "properties": {"repobilityId": "bf78a42bc1ced70b", "scanner": "scanner-primary", "fingerprint": "f6308c6fa82ca5cd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/reference/shape.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6515e6e86d58d5b3", "level": "warning", "message": {"text": "Agent authority lacks a verifier contract: .claude/skills/impeccable/scripts/command-metadata.json"}, "properties": {"repobilityId": "b0a32ab76c325cf7", "scanner": "scanner-primary", "fingerprint": "6515e6e86d58d5b3", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["agent-instructions", "verification", "claude_instruction"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".claude/skills/impeccable/scripts/command-metadata.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-a4b5ef8a89299e6d", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/api/src/main.ts:38"}, "properties": {"repobilityId": "9571a331ca301557", "scanner": "scanner-primary", "fingerprint": "a4b5ef8a89299e6d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6794e6dd7b9a73ab", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/public/sw-push.js:2"}, "properties": {"repobilityId": "8f68fa7b81077f47", "scanner": "scanner-primary", "fingerprint": "6794e6dd7b9a73ab", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-75c217f91033b6fb", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/lib/utils.ts:28"}, "properties": {"repobilityId": "2bf096b0d79ec3f7", "scanner": "scanner-primary", "fingerprint": "75c217f91033b6fb", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-45e3bc5674f56d6f", "level": "none", "message": {"text": "Commented-code block (5 lines) in apps/web/src/features/landing/LandingPage.tsx:7"}, "properties": {"repobilityId": "b64c9c33891d0931", "scanner": "scanner-primary", "fingerprint": "45e3bc5674f56d6f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7ed713518e64d130", "level": "none", "message": {"text": "Commented-code block (6 lines) in .claude/skills/impeccable/scripts/hook-lib.mjs:937"}, "properties": {"repobilityId": "838f1ffd239f6a23", "scanner": "scanner-primary", "fingerprint": "7ed713518e64d130", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1baeff73dee89192", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/live-poll.mjs:18"}, "properties": {"repobilityId": "ddd13bc701b9b8ad", "scanner": "scanner-primary", "fingerprint": "1baeff73dee89192", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-becb02117e6c70ac", "level": "note", "message": {"text": "Legacy-named symbol `withoutOld` in .claude/skills/impeccable/scripts/live-inject.mjs:160"}, "properties": {"repobilityId": "c1b6f2ed637d8554", "scanner": "scanner-primary", "fingerprint": "becb02117e6c70ac", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-59b725839b001371", "level": "none", "message": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/live-inject.mjs:406"}, "properties": {"repobilityId": "2593972ea281ad0f", "scanner": "scanner-primary", "fingerprint": "59b725839b001371", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-065289db7780ebf9", "level": "none", "message": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/live-browser.js:33"}, "properties": {"repobilityId": "e7aba3dfa8588145", "scanner": "scanner-primary", "fingerprint": "065289db7780ebf9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-320a976c097f6373", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/live-browser.js:5519"}, "properties": {"repobilityId": "ff8894216ac124cd", "scanner": "scanner-primary", "fingerprint": "320a976c097f6373", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-2bd2ef47647b33b2", "level": "none", "message": {"text": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/live-wrap.mjs:202"}, "properties": {"repobilityId": "d69a7dd70ce9b057", "scanner": "scanner-primary", "fingerprint": "2bd2ef47647b33b2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-05e243f0463fcf14", "level": "none", "message": {"text": "Commented-code block (11 lines) in .claude/skills/impeccable/scripts/live-server.mjs:537"}, "properties": {"repobilityId": "0b33bb4f0aba9763", "scanner": "scanner-primary", "fingerprint": "05e243f0463fcf14", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b16d90ab0270fff8", "level": "note", "message": {"text": "Legacy-named symbol `singleOld` in .claude/skills/impeccable/scripts/hook-before-edit.mjs:115"}, "properties": {"repobilityId": "cb6984d5f9fad6e4", "scanner": "scanner-primary", "fingerprint": "b16d90ab0270fff8", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-1a30b7179eb597df", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 .claude/skills/impeccable/scripts/modern-screenshot.umd.js:7"}, "properties": {"repobilityId": "58f475f1450f458c", "scanner": "scanner-primary", "fingerprint": "1a30b7179eb597df", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-626ea324dec57349", "level": "note", "message": {"text": "Legacy-named symbol `source_shadow_preview_deprecated` in .claude/skills/impeccable/scripts/live-accept.mjs:131"}, "properties": {"repobilityId": "75d5983cf8e11cf7", "scanner": "scanner-primary", "fingerprint": "626ea324dec57349", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-054d870261600733", "level": "none", "message": {"text": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/live-accept.mjs:469"}, "properties": {"repobilityId": "086d735593552a3c", "scanner": "scanner-primary", "fingerprint": "054d870261600733", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-62220a9221f417e2", "level": "none", "message": {"text": "Commented-code block (6 lines) in .claude/skills/impeccable/scripts/palette.mjs:441"}, "properties": {"repobilityId": "3d163f0146f510e6", "scanner": "scanner-primary", "fingerprint": "62220a9221f417e2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a5453a5c2c1974e4", "level": "note", "message": {"text": "Legacy-named symbol `contextLegacy` in .claude/skills/impeccable/scripts/lib/impeccable-paths.mjs:21"}, "properties": {"repobilityId": "2e4a311cbe43933d", "scanner": "scanner-primary", "fingerprint": "a5453a5c2c1974e4", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-8dd326e9c5123b62", "level": "none", "message": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/lib/design-parser.mjs:39"}, "properties": {"repobilityId": "d336fc9c76a7b1db", "scanner": "scanner-primary", "fingerprint": "8dd326e9c5123b62", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-a472357a5f1f52f0", "level": "none", "message": {"text": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/detector/detect-antipatterns-browser.js:25"}, "properties": {"repobilityId": "08b8e6bba7da6021", "scanner": "scanner-primary", "fingerprint": "a472357a5f1f52f0", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-3dd90d0398203834", "level": "none", "message": {"text": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/detector/engines/static-html/css-cascade.mjs:22"}, "properties": {"repobilityId": "a7f1a7a05612cf6d", "scanner": "scanner-primary", "fingerprint": "3dd90d0398203834", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b047195ee1d8a966", "level": "none", "message": {"text": "Commented-code block (5 lines) in .claude/skills/impeccable/scripts/detector/engines/static-html/detect-html.mjs:195"}, "properties": {"repobilityId": "c534bfb01c031b9d", "scanner": "scanner-primary", "fingerprint": "b047195ee1d8a966", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-65d146684aff3721", "level": "none", "message": {"text": "Commented-code block (10 lines) in .claude/skills/impeccable/scripts/detector/rules/checks.mjs:102"}, "properties": {"repobilityId": "47aa58103e99d321", "scanner": "scanner-primary", "fingerprint": "65d146684aff3721", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-243e862c2143f77a", "level": "none", "message": {"text": "Commented-code block (8 lines) in .claude/skills/impeccable/scripts/detector/shared/constants.mjs:11"}, "properties": {"repobilityId": "469ddf9ceae6fdaa", "scanner": "scanner-primary", "fingerprint": "243e862c2143f77a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-108daeee872ff4de", "level": "none", "message": {"text": "Commented-code block (7 lines) in .claude/skills/impeccable/scripts/detector/browser/injected/index.mjs:17"}, "properties": {"repobilityId": "b20b2af5b269e833", "scanner": "scanner-primary", "fingerprint": "108daeee872ff4de", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-9996447513897762", "level": "note", "message": {"text": "30 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "b3285186f72a5bb9", "scanner": "scanner-primary", "fingerprint": "9996447513897762", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}, {"ruleId": "scanner-6040577660fa76aa", "level": "warning", "message": {"text": "Frontend route `/reservar/:slug` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "49fa108bca43d2fd", "scanner": "scanner-primary", "fingerprint": "6040577660fa76aa", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-cf35c84928e91a15", "level": "warning", "message": {"text": "Frontend route `/qr/:slug` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "3d38b950975cd727", "scanner": "scanner-primary", "fingerprint": "cf35c84928e91a15", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-58e0386a3a620b1d", "level": "warning", "message": {"text": "Frontend route `/establecer-password` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "fe0a4da2cf7d47eb", "scanner": "scanner-primary", "fingerprint": "58e0386a3a620b1d", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-795de5228a4485d7", "level": "warning", "message": {"text": "Frontend route `inicio` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "4f380f65821aa7f9", "scanner": "scanner-primary", "fingerprint": "795de5228a4485d7", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-9c94f996e0376bf2", "level": "warning", "message": {"text": "Frontend route `agenda` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "b8c1749526121f54", "scanner": "scanner-primary", "fingerprint": "9c94f996e0376bf2", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-29da29987fca33e1", "level": "warning", "message": {"text": "Frontend route `calendario-atencion` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "17549f27abdc7a17", "scanner": "scanner-primary", "fingerprint": "29da29987fca33e1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-839d0116e801ede0", "level": "warning", "message": {"text": "Frontend route `pacientes` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "ac2bd13229595d84", "scanner": "scanner-primary", "fingerprint": "839d0116e801ede0", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-09d3c380bb76d303", "level": "warning", "message": {"text": "Frontend route `pacientes/:id` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "36e1d3ac69c3cabe", "scanner": "scanner-primary", "fingerprint": "09d3c380bb76d303", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-cfb1be852696b32f", "level": "warning", "message": {"text": "Frontend route `caja` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "2d813c2c30d5751d", "scanner": "scanner-primary", "fingerprint": "cfb1be852696b32f", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-23ecc90eda59d9d9", "level": "warning", "message": {"text": "Frontend route `gastos` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "3b98e56904ded4af", "scanner": "scanner-primary", "fingerprint": "23ecc90eda59d9d9", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-56b3df96a61ea157", "level": "warning", "message": {"text": "Frontend route `deudores` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "3468167a80ff84c2", "scanner": "scanner-primary", "fingerprint": "56b3df96a61ea157", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3fca1e76ab4cfa73", "level": "warning", "message": {"text": "Frontend route `mensajes` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "e0bce63f64f957c2", "scanner": "scanner-primary", "fingerprint": "3fca1e76ab4cfa73", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-3a2128addff6582a", "level": "warning", "message": {"text": "Frontend route `catalogo` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "e320058514518c87", "scanner": "scanner-primary", "fingerprint": "3a2128addff6582a", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-5f54d38a2ff14d17", "level": "warning", "message": {"text": "Frontend route `ayuda` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "a69f1c81216a30b9", "scanner": "scanner-primary", "fingerprint": "5f54d38a2ff14d17", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-432d09ad9097c807", "level": "warning", "message": {"text": "Frontend route `configuracion` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "7b0b6e0bc947beea", "scanner": "scanner-primary", "fingerprint": "432d09ad9097c807", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-d44750b1514936cd", "level": "warning", "message": {"text": "Frontend route `reportes` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "b3041bb87224f62b", "scanner": "scanner-primary", "fingerprint": "d44750b1514936cd", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-bdc0995d335401df", "level": "warning", "message": {"text": "Frontend route `actividad` has no Link/navigate to it \u2014 apps/web/src/App.tsx"}, "properties": {"repobilityId": "2ae840f7103c8964", "scanner": "scanner-primary", "fingerprint": "bdc0995d335401df", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "orphan-page", "wiring"]}}, {"ruleId": "scanner-44ef15bf59b340c7", "level": "error", "message": {"text": "Dangling fetch: POST http://localhost:${info.port}/poll (.claude/skills/impeccable/scripts/live-complete.mjs:60)"}, "properties": {"repobilityId": "1b13d61954509e21", "scanner": "scanner-primary", "fingerprint": "44ef15bf59b340c7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-115c79099f481498", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:${info.port}/status?token=${info.token} (.claude/skills/impeccable/scripts/live-status.mjs:17)"}, "properties": {"repobilityId": "48818272f42a021d", "scanner": "scanner-primary", "fingerprint": "115c79099f481498", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-417d4143678da048", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:${PORT}/design-system.json?token=${TOKEN} (.claude/skills/impeccable/scripts/live-browser.js:10352)"}, "properties": {"repobilityId": "fe3c0b910f251192", "scanner": "scanner-primary", "fingerprint": "417d4143678da048", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-967238b8ed655f16", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:${PORT}/design-system/raw?token=${TOKEN} (.claude/skills/impeccable/scripts/live-browser.js:10353)"}, "properties": {"repobilityId": "cefa0f6f7149e727", "scanner": "scanner-primary", "fingerprint": "967238b8ed655f16", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-29271db79288bf1f", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:${info.port}/stop?token=${info.token} (.claude/skills/impeccable/scripts/live-server.mjs:1026)"}, "properties": {"repobilityId": "a4d06a8bfeef70d6", "scanner": "scanner-primary", "fingerprint": "29271db79288bf1f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-343160e8bd29b592", "level": "error", "message": {"text": "Dangling fetch: GET http://localhost:${port}/ (.claude/skills/impeccable/scripts/detector/node/file-system.mjs:162)"}, "properties": {"repobilityId": "ca31f4d7af99d727", "scanner": "scanner-primary", "fingerprint": "343160e8bd29b592", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-8292c0931391749a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/register"}, "properties": {"repobilityId": "8aec7980f0bdfa90", "scanner": "scanner-primary", "fingerprint": "8292c0931391749a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8fdbacfe9430a6ed", "level": "note", "message": {"text": "Unused endpoint: POST /auth/login"}, "properties": {"repobilityId": "16b9a3e3838bb882", "scanner": "scanner-primary", "fingerprint": "8fdbacfe9430a6ed", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b36892106ecdc9aa", "level": "note", "message": {"text": "Unused endpoint: POST /auth/refresh"}, "properties": {"repobilityId": "61ada01ae0a00ed9", "scanner": "scanner-primary", "fingerprint": "b36892106ecdc9aa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-cdd0498f1a6e6340", "level": "note", "message": {"text": "Unused endpoint: POST /auth/google"}, "properties": {"repobilityId": "f3037ae2c1398f20", "scanner": "scanner-primary", "fingerprint": "cdd0498f1a6e6340", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-56208bd3b26f952a", "level": "note", "message": {"text": "Unused endpoint: POST /auth/password/solicitar"}, "properties": {"repobilityId": "b38858b464be70a1", "scanner": "scanner-primary", "fingerprint": "56208bd3b26f952a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-92232271fe10cec3", "level": "note", "message": {"text": "Unused endpoint: POST /auth/password/establecer"}, "properties": {"repobilityId": "0331eee235b5ceb4", "scanner": "scanner-primary", "fingerprint": "92232271fe10cec3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7965ee75aa173d71", "level": "note", "message": {"text": "Unused endpoint: DELETE /plantillas-horario/:id"}, "properties": {"repobilityId": "915f9ffce821f96d", "scanner": "scanner-primary", "fingerprint": "7965ee75aa173d71", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-410f8d9c84329ada", "level": "note", "message": {"text": "Unused endpoint: GET /gastos/resumen"}, "properties": {"repobilityId": "d8dcc2614a484fda", "scanner": "scanner-primary", "fingerprint": "410f8d9c84329ada", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-34e455e7edb4a920", "level": "note", "message": {"text": "Unused endpoint: PUT /gastos/:id"}, "properties": {"repobilityId": "1d42e6b185360cea", "scanner": "scanner-primary", "fingerprint": "34e455e7edb4a920", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2e6aaec60d8220f7", "level": "note", "message": {"text": "Unused endpoint: DELETE /gastos/:id"}, "properties": {"repobilityId": "c3c220c0bfb242ee", "scanner": "scanner-primary", "fingerprint": "2e6aaec60d8220f7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f4af7d7c4b5873c6", "level": "note", "message": {"text": "Unused endpoint: GET /caja/hoy"}, "properties": {"repobilityId": "118fd03277020f19", "scanner": "scanner-primary", "fingerprint": "f4af7d7c4b5873c6", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0532506c85091be2", "level": "note", "message": {"text": "Unused endpoint: GET /caja/estado"}, "properties": {"repobilityId": "21a49041a2d1f7a8", "scanner": "scanner-primary", "fingerprint": "0532506c85091be2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-9bd6c041033fb1c3", "level": "note", "message": {"text": "Unused endpoint: POST /caja/abrir"}, "properties": {"repobilityId": "5444f4d6fe2e766f", "scanner": "scanner-primary", "fingerprint": "9bd6c041033fb1c3", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c922ce0e95da1e35", "level": "note", "message": {"text": "Unused endpoint: POST /caja/cerrar"}, "properties": {"repobilityId": "c647a2edd5345d5d", "scanner": "scanner-primary", "fingerprint": "c922ce0e95da1e35", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-af2b533cc152c188", "level": "note", "message": {"text": "Unused endpoint: POST /caja/reabrir"}, "properties": {"repobilityId": "265e51171baa612a", "scanner": "scanner-primary", "fingerprint": "af2b533cc152c188", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-a77fe5432c3f6b54", "level": "note", "message": {"text": "Unused endpoint: PUT /caja/:id/revisar"}, "properties": {"repobilityId": "05c545efd40ac673", "scanner": "scanner-primary", "fingerprint": "a77fe5432c3f6b54", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4f46833e10874e4c", "level": "note", "message": {"text": "Unused endpoint: GET /caja/historial"}, "properties": {"repobilityId": "a12942ddc0fb7f76", "scanner": "scanner-primary", "fingerprint": "4f46833e10874e4c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-24d2cba95660b409", "level": "note", "message": {"text": "Unused endpoint: GET /reportes/mensual"}, "properties": {"repobilityId": "e0a47dfc455698ba", "scanner": "scanner-primary", "fingerprint": "24d2cba95660b409", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d21d1627d3e4675e", "level": "note", "message": {"text": "Unused endpoint: GET /reportes/citas"}, "properties": {"repobilityId": "17fd396ab1e1d2e0", "scanner": "scanner-primary", "fingerprint": "d21d1627d3e4675e", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2550c1ea62a5b7b7", "level": "note", "message": {"text": "Unused endpoint: GET /reportes/cobranzas"}, "properties": {"repobilityId": "959fcdc234c8284b", "scanner": "scanner-primary", "fingerprint": "2550c1ea62a5b7b7", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-259073849467fbf2", "level": "note", "message": {"text": "Unused endpoint: GET /reportes/gastos"}, "properties": {"repobilityId": "e9bec75f2e5efb52", "scanner": "scanner-primary", "fingerprint": "259073849467fbf2", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-091f0eada74f98cc", "level": "note", "message": {"text": "Unused endpoint: GET /reportes/pacientes"}, "properties": {"repobilityId": "fdfe9f94be1685b2", "scanner": "scanner-primary", "fingerprint": "091f0eada74f98cc", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-d3de90324828b515", "level": "note", "message": {"text": "Unused endpoint: GET /reportes/servicios"}, "properties": {"repobilityId": "af302a35e6aafff3", "scanner": "scanner-primary", "fingerprint": "d3de90324828b515", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-893781598880eb54", "level": "note", "message": {"text": "Unused endpoint: PUT /disponibilidades/:id"}, "properties": {"repobilityId": "f381f72548d9a24a", "scanner": "scanner-primary", "fingerprint": "893781598880eb54", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-261a2b843e78f312", "level": "note", "message": {"text": "Unused endpoint: DELETE /disponibilidades/:id"}, "properties": {"repobilityId": "202ac8f79b23bb58", "scanner": "scanner-primary", "fingerprint": "261a2b843e78f312", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3266ae2a89363c04", "level": "note", "message": {"text": "Unused endpoint: GET /atenciones/paciente/:pacienteId"}, "properties": {"repobilityId": "e1ea1f8314206327", "scanner": "scanner-primary", "fingerprint": "3266ae2a89363c04", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-1d1af6b0eb827e98", "level": "note", "message": {"text": "Unused endpoint: GET /atenciones/cita/:citaId"}, "properties": {"repobilityId": "9325de0cbed5627d", "scanner": "scanner-primary", "fingerprint": "1d1af6b0eb827e98", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-2a57e10bde63522d", "level": "note", "message": {"text": "Unused endpoint: PUT /atenciones/cita/:citaId"}, "properties": {"repobilityId": "613100caedf784e9", "scanner": "scanner-primary", "fingerprint": "2a57e10bde63522d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-025d80655efaaeaa", "level": "note", "message": {"text": "Unused endpoint: POST /atenciones/cita/:citaId/adjuntos"}, "properties": {"repobilityId": "6f2eadf2999e71fa", "scanner": "scanner-primary", "fingerprint": "025d80655efaaeaa", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-be00e007110eca00", "level": "note", "message": {"text": "Unused endpoint: GET /atenciones/cita/:citaId/adjuntos/:indice"}, "properties": {"repobilityId": "228d80da5053c497", "scanner": "scanner-primary", "fingerprint": "be00e007110eca00", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7611bbdbea3802f8", "level": "note", "message": {"text": "Unused endpoint: DELETE /atenciones/cita/:citaId/adjuntos/:indice"}, "properties": {"repobilityId": "db75f95b0fac5329", "scanner": "scanner-primary", "fingerprint": "7611bbdbea3802f8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-13f9db208b9b2b71", "level": "note", "message": {"text": "Unused endpoint: POST /atenciones/cita/:citaId/recetas"}, "properties": {"repobilityId": "15e89b1519400010", "scanner": "scanner-primary", "fingerprint": "13f9db208b9b2b71", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-831c3183d234a6e5", "level": "note", "message": {"text": "Unused endpoint: GET /atenciones/cita/:citaId/recetas"}, "properties": {"repobilityId": "fcb25afa76727eb6", "scanner": "scanner-primary", "fingerprint": "831c3183d234a6e5", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-06051e0d56b8db6c", "level": "note", "message": {"text": "Unused endpoint: GET /atenciones/recetas/:id/pdf"}, "properties": {"repobilityId": "c808d4cb05e87776", "scanner": "scanner-primary", "fingerprint": "06051e0d56b8db6c", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f97c937bda4116a8", "level": "note", "message": {"text": "Unused endpoint: PUT /servicios/:id"}, "properties": {"repobilityId": "aae7936ddf6ecd01", "scanner": "scanner-primary", "fingerprint": "f97c937bda4116a8", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4f82a20ee467727f", "level": "note", "message": {"text": "Unused endpoint: DELETE /servicios/:id"}, "properties": {"repobilityId": "70aff33a59f9d2ea", "scanner": "scanner-primary", "fingerprint": "4f82a20ee467727f", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-b0b5c9066f76f11d", "level": "note", "message": {"text": "Unused endpoint: GET /public/:slug"}, "properties": {"repobilityId": "cde5f14c60f852fd", "scanner": "scanner-primary", "fingerprint": "b0b5c9066f76f11d", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3055d5fce6fc29ee", "level": "note", "message": {"text": "Unused endpoint: GET /public/:slug/prefill/:token"}, "properties": {"repobilityId": "f05a073891d843b5", "scanner": "scanner-primary", "fingerprint": "3055d5fce6fc29ee", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-6add6d6c993322d4", "level": "note", "message": {"text": "Unused endpoint: GET /public/:slug/qr"}, "properties": {"repobilityId": "153a7e52045ccf34", "scanner": "scanner-primary", "fingerprint": "6add6d6c993322d4", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-3ea581f819a66a2a", "level": "note", "message": {"text": "Unused endpoint: GET /public/:slug/dias"}, "properties": {"repobilityId": "523f06a0f3c0fa65", "scanner": "scanner-primary", "fingerprint": "3ea581f819a66a2a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c5e89223674d461", "level": "note", "message": {"text": "Unused endpoint: GET /public/:slug/slots"}, "properties": {"repobilityId": "362a9924501c6b81", "scanner": "scanner-primary", "fingerprint": "7c5e89223674d461", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-c1c91f1ecfd6fb0b", "level": "note", "message": {"text": "Unused endpoint: POST /public/:slug/reservas"}, "properties": {"repobilityId": "6ea80609dc10901a", "scanner": "scanner-primary", "fingerprint": "c1c91f1ecfd6fb0b", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-93b40a8e3c787345", "level": "note", "message": {"text": "Unused endpoint: GET /cobros/deudores"}, "properties": {"repobilityId": "412dd9c932865c03", "scanner": "scanner-primary", "fingerprint": "93b40a8e3c787345", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-26c1a7aaffbde143", "level": "note", "message": {"text": "Unused endpoint: GET /cobros/deudores/resumen"}, "properties": {"repobilityId": "940e95669d882968", "scanner": "scanner-primary", "fingerprint": "26c1a7aaffbde143", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-7c63c674d2172411", "level": "note", "message": {"text": "Unused endpoint: GET /cobros/cita/:citaId"}, "properties": {"repobilityId": "73d71ce560a375d8", "scanner": "scanner-primary", "fingerprint": "7c63c674d2172411", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-f03f07b9e18c3235", "level": "note", "message": {"text": "Unused endpoint: PUT /cobros/:id/total"}, "properties": {"repobilityId": "4935a99464617879", "scanner": "scanner-primary", "fingerprint": "f03f07b9e18c3235", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-12fff7c6919581bf", "level": "note", "message": {"text": "Unused endpoint: POST /cobros/:id/pagos"}, "properties": {"repobilityId": "8ec178c4221fcebb", "scanner": "scanner-primary", "fingerprint": "12fff7c6919581bf", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-8e901a6f0b225c61", "level": "note", "message": {"text": "Unused endpoint: POST /cobros/pagos/:id/anular"}, "properties": {"repobilityId": "af7c107f43a98d43", "scanner": "scanner-primary", "fingerprint": "8e901a6f0b225c61", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-4f06149119e5d737", "level": "note", "message": {"text": "Unused endpoint: POST /citas/no-shows/procesar"}, "properties": {"repobilityId": "d6fced937848dbf2", "scanner": "scanner-primary", "fingerprint": "4f06149119e5d737", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-bd8d1c52fc670927", "level": "note", "message": {"text": "Unused endpoint: PUT /citas/:id/estado"}, "properties": {"repobilityId": "62afd5ac6d951f2f", "scanner": "scanner-primary", "fingerprint": "bd8d1c52fc670927", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}