{"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-9ef76ad69550ae75", "name": "Possibly dead Python function: handle_message", "shortDescription": {"text": "Possibly dead Python function: handle_message"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-e2e647b2ac10b319", "name": "Possibly dead Python function: enviar_briefings", "shortDescription": {"text": "Possibly dead Python function: enviar_briefings"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-35f957cdfca533b8", "name": "Possibly dead Python function: enviar_seguimiento", "shortDescription": {"text": "Possibly dead Python function: enviar_seguimiento"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6eb5da3833f49522", "name": "Possibly dead Python function: generar_snapshot_diario", "shortDescription": {"text": "Possibly dead Python function: generar_snapshot_diario"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-0fbd3a09f265e10e", "name": "Possibly dead Python function: delta", "shortDescription": {"text": "Possibly dead Python function: delta"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-329848d50be7210a", "name": "Possibly dead Python function: tendencia_capital", "shortDescription": {"text": "Possibly dead Python function: tendencia_capital"}, "fullDescription": {"text": "No callers detected by AST scan in this repo. Could be exported for external callers or a framework handler."}, "properties": {"scanner": "scanner-primary", "layer": "software", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ac77cae3f7a2cc60", "name": "Stray `console.log` in TS/JS \u2014 scripts/audit-stock-propio.ts:53", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/audit-stock-propio.ts:53"}, "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-174571fbe63fa357", "name": "Stray `console.log` in TS/JS \u2014 scripts/ejemplos-fecha-factura.ts:54", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/ejemplos-fecha-factura.ts:54"}, "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-8540a02c452838d0", "name": "Stray `console.log` in TS/JS \u2014 scripts/validar-cuadratura-marca.ts:81", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/validar-cuadratura-marca.ts:81"}, "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-2ae9b9a4b513b852", "name": "Stray `console.log` in TS/JS \u2014 scripts/historico-backfill.ts:77", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/historico-backfill.ts:77"}, "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-5b3c42139bfe8fe3", "name": "Stray `console.log` in TS/JS \u2014 scripts/diagnostico-atribucion-marca.ts:61", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/diagnostico-atribucion-marca.ts:61"}, "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-6c5bf330660a4400", "name": "Stray `console.log` in TS/JS \u2014 scripts/historico-recalcular.ts:48", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/historico-recalcular.ts:48"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ffcf3bd2d6539716", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/alertas/page.tsx:581", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/alertas/page.tsx:581"}, "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-4673f204265d5e3d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/dashboard/page.tsx:1089", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/dashboard/page.tsx:1089"}, "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-ed9c993b55285c2b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/kia/page.tsx:814", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/kia/page.tsx:814"}, "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-c4ff5ba8ee5d7ce0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/stock/page.tsx:495", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/stock/page.tsx:495"}, "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-6baab6aaf3cbf195", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/capital-pagado/page.tsx:483", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/capital-pagado/page.tsx:483"}, "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-0b21982d9344b4c6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/facturados-no-entregados/page.tsx:621", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/facturados-no-entregados/page.tsx:621"}, "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-037e17713e0e3104", "name": "Stray `console.log` in TS/JS \u2014 src/app/api/snapshot/route.ts:82", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 src/app/api/snapshot/route.ts:82"}, "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-f47f2dd6befc364b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/tescar/page.tsx:120", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/tescar/page.tsx:120"}, "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-bbeaea1da829e232", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/saldos/page.tsx:531", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/saldos/page.tsx:531"}, "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-9012108bdf5e12a0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/centro-accion/page.tsx:1395", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/centro-accion/page.tsx:1395"}, "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-44c58f6b886539f1", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/ingesta/page.tsx:191", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/ingesta/page.tsx:191"}, "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-c5b4324435ad2660", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/vu-en-fne/page.tsx:580", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/vu-en-fne/page.tsx:580"}, "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-b9f2933b5aa5e5ec", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/validacion/page.tsx:283", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/validacion/page.tsx:283"}, "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-0ca9b8b9c07b4d75", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/provisiones/page.tsx:259", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/provisiones/page.tsx:259"}, "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-122e3804203a80cc", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/capital-trabajo/page.tsx:930", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/capital-trabajo/page.tsx:930"}, "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-523f5f976124042f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/usados/page.tsx:682", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/usados/page.tsx:682"}, "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-4b6ecd4d4150bd94", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/lineas/page.tsx:579", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/lineas/page.tsx:579"}, "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-3398d21ef678828b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/GestionInline.tsx:244", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/GestionInline.tsx:244"}, "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-6b03c5e208f9f827", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadLogisticaButton.tsx:192", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadLogisticaButton.tsx:192"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-018c926ddf86dfc4", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadProvisionesButton.tsx:96", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadProvisionesButton.tsx:96"}, "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-50e1e3ae140a1e07", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/RazonesScore.tsx:47", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/RazonesScore.tsx:47"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-ce5788eb5b30ecbe", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/Sidebar.tsx:171", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Sidebar.tsx:171"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-eaddcd167e4242d0", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadFNEButton.tsx:105", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadFNEButton.tsx:105"}, "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-0adfd5d6b76d5d82", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadSaldosButton.tsx:89", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadSaldosButton.tsx:89"}, "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-91a83a3af1fdcaf5", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AsignarTareaModal.tsx:222", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AsignarTareaModal.tsx:222"}, "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-c4a8f9de9c503ec2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/AbrirCasoButton.tsx:69", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AbrirCasoButton.tsx:69"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-555468344dcd873f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/VinDrillTable.tsx:106", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/VinDrillTable.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-cbf6e7bc716d6aa2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/CasoModal.tsx:50", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/CasoModal.tsx:50"}, "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-2af4fe682c51dfbd", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/FichaOperacionalVIN.tsx:678", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/FichaOperacionalVIN.tsx:678"}, "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-ea2d74763599f94d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/logistica/ColaGestionableLog.tsx:102", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/logistica/ColaGestionableLog.tsx:102"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-6a5d42193518246b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/FNEGrupoCard.tsx:141", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/FNEGrupoCard.tsx:141"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-372d696e3b2dc187", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/ProcesoQuebradoCard.tsx:116", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/ProcesoQuebradoCard.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-92299af09ef5d7f7", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/ColaGestionableCN.tsx:162", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/ColaGestionableCN.tsx:162"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-8692e1c074eab324", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/RankingsSection.tsx:204", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/RankingsSection.tsx:204"}, "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-1e3b97619d6f9905", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/tendencias/GraficosCapital.tsx:77", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/tendencias/GraficosCapital.tsx:77"}, "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-fa28a62bec2e477c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/ColaGestionableHistorico.tsx:131", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/ColaGestionableHistorico.tsx:131"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-7d4ff1ee2f66f838", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FunnelProcesoCerrado.tsx:389", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FunnelProcesoCerrado.tsx:389"}, "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-bda20e6ae9ce85d3", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/BacklogFacturaView.tsx:235", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/BacklogFacturaView.tsx:235"}, "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-a122c2616de569ea", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EjeCumplimientoCard.tsx:66", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EjeCumplimientoCard.tsx:66"}, "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-c9d0779d97479830", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/CierreCumplimientoMes.tsx:198", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/CierreCumplimientoMes.tsx:198"}, "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-69f4c23b0dd0a75f", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FunnelHitosFactura.tsx:221", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FunnelHitosFactura.tsx:221"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-2ebce2c9815d76c8", "name": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/ProcesoSelector.tsx:65", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/ProcesoSelector.tsx:65"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-dcc877ed0d471e37", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FaltantesProcesoSection.tsx:115", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FaltantesProcesoSection.tsx:115"}, "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-fa15d72b55dfbc31", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/TimelineProcesoCard.tsx:104", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/TimelineProcesoCard.tsx:104"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-12ea4969dd335bf9", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EstadoCargaColapsible.tsx:109", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EstadoCargaColapsible.tsx:109"}, "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-ca90240ac3ac2603", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EstadoCargaPanel.tsx:44", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EstadoCargaPanel.tsx:44"}, "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-32218cbda0d747ed", "name": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/EjeTabs.tsx:54", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/EjeTabs.tsx:54"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-04c337dfd851c026", "name": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/ModoProcesoToggle.tsx:58", "shortDescription": {"text": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/ModoProcesoToggle.tsx:58"}, "fullDescription": {"text": "A ternary like `active ? 'bg-white' : '...'` (or bg-gray-100/200) on a dark theme produces jarring white pills. Use a dark-emphasized active state instead \u2014 border + ring or slightly brighter dark bg. Example: `active ? 'bg-gray-800 border-gray-500 ring-1 ring-blue-500/30' : '\u2026'`.\n\nWhy: P-E in CHECKLIST.md \u2014 light bg in a dark theme is a class of regression.\nRule id: fq.active-light-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ecfb717cb5ede54c", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/StockNoDisponible.tsx:68", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/StockNoDisponible.tsx:68"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-62da977642c0dff3", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/IndicadorResumido.tsx:69", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/IndicadorResumido.tsx:69"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-91e23e6abdfb918a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/ColaIndicador.tsx:368", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/ColaIndicador.tsx:368"}, "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-ac753df185d3601a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/PlanLlegarA100Banner.tsx:102", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/PlanLlegarA100Banner.tsx:102"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d7842905d86a63b2", "name": "React Flow edge with `label=` but no project-wide edge-label CSS override \u2014 src/lib/historico/vista-derivados.ts:1286", "shortDescription": {"text": "React Flow edge with `label=` but no project-wide edge-label CSS override \u2014 src/lib/historico/vista-derivados.ts:1286"}, "fullDescription": {"text": "React Flow edge labels render with a white rectangle behind the text by default, which scatters bright boxes across a dark canvas. Either drop the label, or override `.react-flow__edge-textbg` and `.react-flow__edge-text` in your stylesheet.\n\nWhy: P-H in CHECKLIST.md \u2014 vendor edge labels bleed white through a dark canvas.\nRule id: fq.edge-label.no-bg"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-ca79160d355d7c34", "name": "TODO/FIXME marker in shipping code \u2014 src/lib/selectors/razones-bloqueo.ts:28", "shortDescription": {"text": "TODO/FIXME marker in shipping code \u2014 src/lib/selectors/razones-bloqueo.ts:28"}, "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-d63da3583b14afc0", "name": "Dockerfile runs as root: Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8987d6d1c30c7202", "name": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-f954f3ec6cf33df5", "name": "Dockerfile runs as root: agent/Dockerfile", "shortDescription": {"text": "Dockerfile runs as root: agent/Dockerfile"}, "fullDescription": {"text": "No non-root USER set. Containers running as root expand the blast radius of any vulnerability inside the image."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-773dbb11490de160", "name": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim", "shortDescription": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "fullDescription": {"text": "Container tags can be retagged upstream. Pin production base images to a reviewed digest (`image@sha256:...`) when reproducibility and supply-chain integrity matter."}, "properties": {"scanner": "scanner-primary", "layer": "hardware", "severity": "low", "confidence": 1.0}}, {"id": "scanner-7f06ee765dc21555", "name": "Insecure pattern 'node_child_process' in diag/diagnostico-conflicto-ffactura.mjs:11", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/diagnostico-conflicto-ffactura.mjs:11"}, "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-5ec44f53a18917aa", "name": "Insecure pattern 'node_child_process' in diag/validar-cruce-vs-csv.mjs:20", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-cruce-vs-csv.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-1c8682a4550f07e5", "name": "Insecure pattern 'node_child_process' in diag/validar-vista-vs-cruce.mjs:15", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-vista-vs-cruce.mjs:15"}, "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-05fe7bd909eba758", "name": "Insecure pattern 'node_child_process' in diag/validar-consolidador-actas-mono-corte.mjs:16", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-consolidador-actas-mono-corte.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-e41c3f75f27c9a95", "name": "Insecure pattern 'node_child_process' in diag/validar-parser-actas-vs-csv.mjs:20", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-parser-actas-vs-csv.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-4189d8490e0b41a7", "name": "Insecure pattern 'node_child_process' in diag/validar-consolidador-actas-vs-csv.mjs:21", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-consolidador-actas-vs-csv.mjs:21"}, "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-a83233e9a29b47ee", "name": "Insecure pattern 'node_child_process' in diag/diagnostico-conflicto-finscripcion.mjs:27", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/diagnostico-conflicto-finscripcion.mjs:27"}, "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-5574202956788116", "name": "Insecure pattern 'node_child_process' in diag/validar-consolidador-vs-csv.mjs:16", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-consolidador-vs-csv.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-92b46083a331c7fa", "name": "Insecure pattern 'node_child_process' in diag/validar-parser-roma-vs-csv.mjs:20", "shortDescription": {"text": "Insecure pattern 'node_child_process' in diag/validar-parser-roma-vs-csv.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-28c4a04bd807da0c", "name": "GitHub Action is tag-pinned rather than SHA-pinned", "shortDescription": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "fullDescription": {"text": "actions/checkout@v4 can move without a code change in this repo. Pin third-party actions to a reviewed 40-character commit SHA."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1b94ff6727bae3f0", "name": "Very large file: src/app/dashboard/page.tsx (2923 lines)", "shortDescription": {"text": "Very large file: src/app/dashboard/page.tsx (2923 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-4ad8875fd5bedf38", "name": "Very large file: src/app/kia/page.tsx (1397 lines)", "shortDescription": {"text": "Very large file: src/app/kia/page.tsx (1397 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-fe00d11e4a7231e2", "name": "Very large file: src/app/facturados-no-entregados/page.tsx (1439 lines)", "shortDescription": {"text": "Very large file: src/app/facturados-no-entregados/page.tsx (1439 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-156233730a9040bf", "name": "Very large file: src/app/centro-accion/page.tsx (2507 lines)", "shortDescription": {"text": "Very large file: src/app/centro-accion/page.tsx (2507 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-b0979fb2ea31d5ab", "name": "Very large file: src/app/capital-trabajo/page.tsx (1365 lines)", "shortDescription": {"text": "Very large file: src/app/capital-trabajo/page.tsx (1365 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-a05f8b7b7b305e7f", "name": "Very large file: src/lib/historico/vista-derivados.ts (2428 lines)", "shortDescription": {"text": "Very large file: src/lib/historico/vista-derivados.ts (2428 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-7cbd459306894940", "name": "Very large file: src/lib/historico/__tests__/vista-derivados.test.ts (1588 lines)", "shortDescription": {"text": "Very large file: src/lib/historico/__tests__/vista-derivados.test.ts (1588 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": "9 test file(s) for 361 source file(s) (ratio 0.02). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8d0501dd6688c007", "name": "81 TODO/FIXME markers", "shortDescription": {"text": "81 TODO/FIXME markers"}, "fullDescription": {"text": "High count of TODO/FIXME/HACK markers \u2014 track them as issues so they're not forgotten."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 2367 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 35 placeholder/mock markers across 12 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-8150b4100e15ae2e", "name": "Commented-code block (5 lines) in scripts/verify-gestion.mjs:1", "shortDescription": {"text": "Commented-code block (5 lines) in scripts/verify-gestion.mjs:1"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-f69e6ee524198dd9", "name": "Commented-code block (11 lines) in agent/tools.py:472", "shortDescription": {"text": "Commented-code block (11 lines) in agent/tools.py:472"}, "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-1d7f4638cd8442f6", "name": "Commented-code block (5 lines) in diag/redefinir-doc-listo.mjs:288", "shortDescription": {"text": "Commented-code block (5 lines) in diag/redefinir-doc-listo.mjs:288"}, "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-13ba2ff9017adff3", "name": "Commented-code block (9 lines) in src/app/dashboard/page.tsx:155", "shortDescription": {"text": "Commented-code block (9 lines) in src/app/dashboard/page.tsx:155"}, "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-4c36f0b552ee5526", "name": "Commented-code block (5 lines) in src/app/api/snapshot/route.ts:143", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/api/snapshot/route.ts:143"}, "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-b1c7172e50cc5fba", "name": "Commented-code block (5 lines) in src/app/centro-accion/page.tsx:356", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/centro-accion/page.tsx:356"}, "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-7bae4ecb3fca693d", "name": "Commented-code block (5 lines) in src/app/tendencias/page.tsx:105", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/tendencias/page.tsx:105"}, "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-d72a901b0a960bc8", "name": "Commented-code block (5 lines) in src/app/operaciones/control-de-negocio/page.tsx:163", "shortDescription": {"text": "Commented-code block (5 lines) in src/app/operaciones/control-de-negocio/page.tsx:163"}, "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-f6a2bd3173b320c6", "name": "Commented-code block (7 lines) in src/components/SnapshotHydrator.tsx:127", "shortDescription": {"text": "Commented-code block (7 lines) in src/components/SnapshotHydrator.tsx:127"}, "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-248254e79d3cf8c3", "name": "Commented-code block (7 lines) in src/lib/ventas-q1.ts:99", "shortDescription": {"text": "Commented-code block (7 lines) in src/lib/ventas-q1.ts:99"}, "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-5002216c467b5247", "name": "Commented-code block (5 lines) in src/lib/types.ts:122", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/types.ts:122"}, "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-0ae98885a8951015", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/snapshot-client.ts:177", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/snapshot-client.ts:177"}, "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-95189ee1acba8465", "name": "Commented-code block (6 lines) in src/lib/parser/romia-logistica.ts:187", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/parser/romia-logistica.ts:187"}, "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-eb0cb735ac22a9ca", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/gestion/store.ts:178", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/gestion/store.ts:178"}, "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-765d4090f48bd37e", "name": "Commented-code block (5 lines) in src/lib/gestion/types.ts:21", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/gestion/types.ts:21"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-0429b33dc2fb2945", "name": "Commented-code block (8 lines) in src/lib/logistica/construir.ts:202", "shortDescription": {"text": "Commented-code block (8 lines) in src/lib/logistica/construir.ts: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-c13cb25e79f7d989", "name": "Commented-code block (5 lines) in src/lib/control-de-negocio/cn-universo.ts:127", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/control-de-negocio/cn-universo.ts:127"}, "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-0efe11337fc6ccba", "name": "Commented-code block (9 lines) in src/lib/ingesta/procesar.ts:286", "shortDescription": {"text": "Commented-code block (9 lines) in src/lib/ingesta/procesar.ts:286"}, "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-bdf7d21ada650e5f", "name": "Commented-code block (5 lines) in src/lib/historico/consolidar-periodo.ts:146", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/historico/consolidar-periodo.ts:146"}, "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-f9653ff5b65a981a", "name": "Legacy-named symbol `sgLegacy` in src/lib/historico/calcular-scores-por-dia.ts:76", "shortDescription": {"text": "Legacy-named symbol `sgLegacy` in src/lib/historico/calcular-scores-por-dia.ts:76"}, "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-9fbfb402ede410d2", "name": "Commented-code block (5 lines) in src/lib/historico/persistir.ts:485", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/historico/persistir.ts:485"}, "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-abb80ae06400ba07", "name": "Commented-code block (9 lines) in src/lib/historico/vista-derivados.ts:713", "shortDescription": {"text": "Commented-code block (9 lines) in src/lib/historico/vista-derivados.ts:713"}, "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-017b5a70f4aefc73", "name": "Commented-code block (5 lines) in src/lib/selectors/vehiculo-unificado.ts:366", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/selectors/vehiculo-unificado.ts:366"}, "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-dad44d81a6bda6d4", "name": "Commented-code block (6 lines) in src/lib/selectors/usados-operacional.ts:210", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/selectors/usados-operacional.ts:210"}, "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-dee7741be46653e8", "name": "Commented-code block (5 lines) in src/lib/selectors/score-gerencial.ts:178", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/selectors/score-gerencial.ts:178"}, "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-4ccee41a7bf4cc14", "name": "Commented-code block (5 lines) in src/lib/selectors/capital-trabajo-marca.ts:97", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/selectors/capital-trabajo-marca.ts:97"}, "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-cca15a19bf9e8711", "name": "Commented-code block (6 lines) in src/lib/selectors/owner-operacional.ts:274", "shortDescription": {"text": "Commented-code block (6 lines) in src/lib/selectors/owner-operacional.ts:274"}, "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-6191d9d7c7c2e73c", "name": "Commented-code block (5 lines) in src/lib/selectors/vu-en-fne.ts:141", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/selectors/vu-en-fne.ts:141"}, "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-2d8f718a55c03e9a", "name": "Commented-code block (7 lines) in src/lib/selectors/hero-operacional.ts:120", "shortDescription": {"text": "Commented-code block (7 lines) in src/lib/selectors/hero-operacional.ts:120"}, "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-ce3502fd58613053", "name": "FastAPI POST `receive_webhook` without auth dependency \u2014 agent/webhook.py:54", "shortDescription": {"text": "FastAPI POST `receive_webhook` without auth dependency \u2014 agent/webhook.py:54"}, "fullDescription": {"text": "`@router.post` decorator with no `Depends(get_current_user)` or auth-shaped dependency in its signature. Mutating endpoints should require authentication unless explicitly public."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "high", "confidence": 1.0}}, {"id": "scanner-e9a442bef1b0f3ec", "name": "Dangling fetch: POST /api/admin/users (src/app/usuarios/page.tsx:93)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/users (src/app/usuarios/page.tsx:93)"}, "fullDescription": {"text": "`src/app/usuarios/page.tsx:93` calls `POST /api/admin/users` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users`\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-9e9a67a6f9922f0f", "name": "Dangling fetch: POST /api/admin/users/${user.id}/reset-password (src/app/usuarios/page.tsx:168)", "shortDescription": {"text": "Dangling fetch: POST /api/admin/users/${user.id}/reset-password (src/app/usuarios/page.tsx:168)"}, "fullDescription": {"text": "`src/app/usuarios/page.tsx:168` calls `POST /api/admin/users/${user.id}/reset-password` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users/<p>/reset-password`\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-83860722eb3014ea", "name": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:236)", "shortDescription": {"text": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:236)"}, "fullDescription": {"text": "`src/app/usuarios/page.tsx:236` calls `PATCH /api/admin/users/${user.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users/<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-6b5d3387ee26b04a", "name": "Dangling fetch: GET /api/admin/users (src/app/usuarios/page.tsx:352)", "shortDescription": {"text": "Dangling fetch: GET /api/admin/users (src/app/usuarios/page.tsx:352)"}, "fullDescription": {"text": "`src/app/usuarios/page.tsx:352` calls `GET /api/admin/users` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users`\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-6819634c1e0e08c7", "name": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:362)", "shortDescription": {"text": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:362)"}, "fullDescription": {"text": "`src/app/usuarios/page.tsx:362` calls `PATCH /api/admin/users/${user.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users/<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-84d78200fbae88d2", "name": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:376)", "shortDescription": {"text": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:376)"}, "fullDescription": {"text": "`src/app/usuarios/page.tsx:376` calls `PATCH /api/admin/users/${user.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/admin/users/<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-1b40a260b27e4f7e", "name": "Dangling fetch: POST /api/snapshots/daily (src/app/tendencias/GenerarSnapshotHoy.tsx:20)", "shortDescription": {"text": "Dangling fetch: POST /api/snapshots/daily (src/app/tendencias/GenerarSnapshotHoy.tsx:20)"}, "fullDescription": {"text": "`src/app/tendencias/GenerarSnapshotHoy.tsx:20` calls `POST /api/snapshots/daily` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/snapshots/daily`\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-e50fc7429d0c24ec", "name": "Dangling fetch: GET /api/notificaciones${FILTRO_QS[filtro]} (src/app/notificaciones/page.tsx:85)", "shortDescription": {"text": "Dangling fetch: GET /api/notificaciones${FILTRO_QS[filtro]} (src/app/notificaciones/page.tsx:85)"}, "fullDescription": {"text": "`src/app/notificaciones/page.tsx:85` calls `GET /api/notificaciones${FILTRO_QS[filtro]}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/notificaciones/<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-97b0184c463e9464", "name": "Dangling fetch: PATCH /api/notificaciones/${a.id} (src/app/notificaciones/page.tsx:111)", "shortDescription": {"text": "Dangling fetch: PATCH /api/notificaciones/${a.id} (src/app/notificaciones/page.tsx:111)"}, "fullDescription": {"text": "`src/app/notificaciones/page.tsx:111` calls `PATCH /api/notificaciones/${a.id}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/notificaciones/<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-41ddbeed8b6fa542", "name": "Dangling fetch: GET /api/snapshot?fuente=BASE_STOCK (src/components/Header.tsx:26)", "shortDescription": {"text": "Dangling fetch: GET /api/snapshot?fuente=BASE_STOCK (src/components/Header.tsx:26)"}, "fullDescription": {"text": "`src/components/Header.tsx:26` calls `GET /api/snapshot?fuente=BASE_STOCK` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/snapshot`\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-7ebf980fdf528acf", "name": "Dangling fetch: GET /api/usuarios-asignables (src/components/AsignarTareaModal.tsx:111)", "shortDescription": {"text": "Dangling fetch: GET /api/usuarios-asignables (src/components/AsignarTareaModal.tsx:111)"}, "fullDescription": {"text": "`src/components/AsignarTareaModal.tsx:111` calls `GET /api/usuarios-asignables` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/usuarios-asignables`\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-3d0dcb2e40c6bfcd", "name": "Dangling fetch: POST /api/tareas (src/components/AsignarTareaModal.tsx:174)", "shortDescription": {"text": "Dangling fetch: POST /api/tareas (src/components/AsignarTareaModal.tsx:174)"}, "fullDescription": {"text": "`src/components/AsignarTareaModal.tsx:174` calls `POST /api/tareas` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/tareas`\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-81af2b9e02a4881a", "name": "Dangling fetch: POST /api/snapshot (src/lib/snapshot-client.ts:136)", "shortDescription": {"text": "Dangling fetch: POST /api/snapshot (src/lib/snapshot-client.ts:136)"}, "fullDescription": {"text": "`src/lib/snapshot-client.ts:136` calls `POST /api/snapshot` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/snapshot`\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-d33e61b64af48952", "name": "Dangling fetch: GET /api/snapshot/active?${qs} (src/lib/snapshot-client.ts:177)", "shortDescription": {"text": "Dangling fetch: GET /api/snapshot/active?${qs} (src/lib/snapshot-client.ts:177)"}, "fullDescription": {"text": "`src/lib/snapshot-client.ts:177` calls `GET /api/snapshot/active?${qs}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/snapshot/active`\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-88bc50f358844c15", "name": "Dangling fetch: GET /api/gestion (src/lib/gestion/store.ts:145)", "shortDescription": {"text": "Dangling fetch: GET /api/gestion (src/lib/gestion/store.ts:145)"}, "fullDescription": {"text": "`src/lib/gestion/store.ts:145` calls `GET /api/gestion` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/gestion`\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-b1a9276e80e004b1", "name": "Dangling fetch: PUT /api/gestion/${encodeURIComponent(vin)} (src/lib/gestion/store.ts:178)", "shortDescription": {"text": "Dangling fetch: PUT /api/gestion/${encodeURIComponent(vin)} (src/lib/gestion/store.ts:178)"}, "fullDescription": {"text": "`src/lib/gestion/store.ts:178` calls `PUT /api/gestion/${encodeURIComponent(vin)}` but no backend route matches that path. This is a runtime 404 waiting to happen.\n\nTool: fetch\nNormalized path used for matching: `/gestion/<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-c251e9b16c727c7a", "name": "Unused endpoint: GET /webhook", "shortDescription": {"text": "Unused endpoint: GET /webhook"}, "fullDescription": {"text": "`agent/webhook.py` declares `GET /webhook` 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-0ae38010c60493f1", "name": "Unused endpoint: POST /webhook", "shortDescription": {"text": "Unused endpoint: POST /webhook"}, "fullDescription": {"text": "`agent/webhook.py` declares `POST /webhook` 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-36ea8bcc0eb74343", "name": "Unused endpoint: GET /debug/estado", "shortDescription": {"text": "Unused endpoint: GET /debug/estado"}, "fullDescription": {"text": "`agent/webhook.py` declares `GET /debug/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-5ad70b0e1d736ab9", "name": "Unused endpoint: GET /debug/tareas", "shortDescription": {"text": "Unused endpoint: GET /debug/tareas"}, "fullDescription": {"text": "`agent/webhook.py` declares `GET /debug/tareas` 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-76b98fc9e33f6933", "name": "Unused endpoint: GET /debug/tareas/ciclo", "shortDescription": {"text": "Unused endpoint: GET /debug/tareas/ciclo"}, "fullDescription": {"text": "`agent/webhook.py` declares `GET /debug/tareas/ciclo` 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-45b1456f013f67da", "name": "Unused endpoint: GET /debug/user/{telefono}", "shortDescription": {"text": "Unused endpoint: GET /debug/user/{telefono}"}, "fullDescription": {"text": "`agent/webhook.py` declares `GET /debug/user/{telefono}` 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/24892"}, "properties": {"repository": "chalf-ai/velocidad", "repoUrl": "https://github.com/chalf-ai/velocidad", "branch": "main"}, "results": [{"ruleId": "scanner-9ef76ad69550ae75", "level": "note", "message": {"text": "Possibly dead Python function: handle_message"}, "properties": {"repobilityId": "7f964a0988a310b8", "scanner": "scanner-primary", "fingerprint": "9ef76ad69550ae75", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/webhook.py:73"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-e2e647b2ac10b319", "level": "note", "message": {"text": "Possibly dead Python function: enviar_briefings"}, "properties": {"repobilityId": "904d3eca204bedba", "scanner": "scanner-primary", "fingerprint": "e2e647b2ac10b319", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/cron.py:37"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-35f957cdfca533b8", "level": "note", "message": {"text": "Possibly dead Python function: enviar_seguimiento"}, "properties": {"repobilityId": "6e132f2e273ab661", "scanner": "scanner-primary", "fingerprint": "35f957cdfca533b8", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/cron.py:61"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-6eb5da3833f49522", "level": "note", "message": {"text": "Possibly dead Python function: generar_snapshot_diario"}, "properties": {"repobilityId": "50a1a404e6b1f81e", "scanner": "scanner-primary", "fingerprint": "6eb5da3833f49522", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/cron.py:99"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-0fbd3a09f265e10e", "level": "note", "message": {"text": "Possibly dead Python function: delta"}, "properties": {"repobilityId": "5996427b162a19d5", "scanner": "scanner-primary", "fingerprint": "0fbd3a09f265e10e", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/tools.py:195"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-329848d50be7210a", "level": "note", "message": {"text": "Possibly dead Python function: tendencia_capital"}, "properties": {"repobilityId": "04d498f9a7b6fcf1", "scanner": "scanner-primary", "fingerprint": "329848d50be7210a", "layer": "software", "severity": "low", "confidence": 1.0, "tags": ["dead-code"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/tools.py:205"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-ac77cae3f7a2cc60", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/audit-stock-propio.ts:53"}, "properties": {"repobilityId": "e3aaa53f94bd9fe0", "scanner": "scanner-primary", "fingerprint": "ac77cae3f7a2cc60", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-174571fbe63fa357", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/ejemplos-fecha-factura.ts:54"}, "properties": {"repobilityId": "9189e4b0beca2a6d", "scanner": "scanner-primary", "fingerprint": "174571fbe63fa357", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8540a02c452838d0", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/validar-cuadratura-marca.ts:81"}, "properties": {"repobilityId": "1bd11c72799144f6", "scanner": "scanner-primary", "fingerprint": "8540a02c452838d0", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-2ae9b9a4b513b852", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/historico-backfill.ts:77"}, "properties": {"repobilityId": "4400756f4300ecaf", "scanner": "scanner-primary", "fingerprint": "2ae9b9a4b513b852", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-5b3c42139bfe8fe3", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/diagnostico-atribucion-marca.ts:61"}, "properties": {"repobilityId": "78044caca2eb5a8d", "scanner": "scanner-primary", "fingerprint": "5b3c42139bfe8fe3", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-6c5bf330660a4400", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/historico-recalcular.ts:48"}, "properties": {"repobilityId": "fd172d9adf89dac4", "scanner": "scanner-primary", "fingerprint": "6c5bf330660a4400", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-ffcf3bd2d6539716", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/alertas/page.tsx:581"}, "properties": {"repobilityId": "1925c63253ba5bbf", "scanner": "scanner-primary", "fingerprint": "ffcf3bd2d6539716", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4673f204265d5e3d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/dashboard/page.tsx:1089"}, "properties": {"repobilityId": "4ba209c1bd3eacfd", "scanner": "scanner-primary", "fingerprint": "4673f204265d5e3d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ed9c993b55285c2b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/kia/page.tsx:814"}, "properties": {"repobilityId": "984364777500ac4e", "scanner": "scanner-primary", "fingerprint": "ed9c993b55285c2b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c4ff5ba8ee5d7ce0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/stock/page.tsx:495"}, "properties": {"repobilityId": "5490ef077397dfdb", "scanner": "scanner-primary", "fingerprint": "c4ff5ba8ee5d7ce0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6baab6aaf3cbf195", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/capital-pagado/page.tsx:483"}, "properties": {"repobilityId": "2909ddc19691b865", "scanner": "scanner-primary", "fingerprint": "6baab6aaf3cbf195", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0b21982d9344b4c6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/facturados-no-entregados/page.tsx:621"}, "properties": {"repobilityId": "ddacf48767759aec", "scanner": "scanner-primary", "fingerprint": "0b21982d9344b4c6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-037e17713e0e3104", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 src/app/api/snapshot/route.ts:82"}, "properties": {"repobilityId": "a9da047beb9d5e4e", "scanner": "scanner-primary", "fingerprint": "037e17713e0e3104", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-f47f2dd6befc364b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/tescar/page.tsx:120"}, "properties": {"repobilityId": "8b53cea6dd329f0d", "scanner": "scanner-primary", "fingerprint": "f47f2dd6befc364b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bbeaea1da829e232", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/saldos/page.tsx:531"}, "properties": {"repobilityId": "3b1051a2c6626e7e", "scanner": "scanner-primary", "fingerprint": "bbeaea1da829e232", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-9012108bdf5e12a0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/centro-accion/page.tsx:1395"}, "properties": {"repobilityId": "03e5f69ad1639fb1", "scanner": "scanner-primary", "fingerprint": "9012108bdf5e12a0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-44c58f6b886539f1", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/ingesta/page.tsx:191"}, "properties": {"repobilityId": "4f966b0743b42286", "scanner": "scanner-primary", "fingerprint": "44c58f6b886539f1", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c5b4324435ad2660", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/vu-en-fne/page.tsx:580"}, "properties": {"repobilityId": "fb5e61eaf35ba141", "scanner": "scanner-primary", "fingerprint": "c5b4324435ad2660", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b9f2933b5aa5e5ec", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/validacion/page.tsx:283"}, "properties": {"repobilityId": "7eee3c3c7262ef8a", "scanner": "scanner-primary", "fingerprint": "b9f2933b5aa5e5ec", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0ca9b8b9c07b4d75", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/provisiones/page.tsx:259"}, "properties": {"repobilityId": "1cc00b345a974045", "scanner": "scanner-primary", "fingerprint": "0ca9b8b9c07b4d75", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-122e3804203a80cc", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/capital-trabajo/page.tsx:930"}, "properties": {"repobilityId": "4280af24df1e9c52", "scanner": "scanner-primary", "fingerprint": "122e3804203a80cc", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-523f5f976124042f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/usados/page.tsx:682"}, "properties": {"repobilityId": "e0e2f1aa6d81fdca", "scanner": "scanner-primary", "fingerprint": "523f5f976124042f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-4b6ecd4d4150bd94", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/lineas/page.tsx:579"}, "properties": {"repobilityId": "ef8cafb483dbaca8", "scanner": "scanner-primary", "fingerprint": "4b6ecd4d4150bd94", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-3398d21ef678828b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/GestionInline.tsx:244"}, "properties": {"repobilityId": "9779b372fe7bb85d", "scanner": "scanner-primary", "fingerprint": "3398d21ef678828b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6b03c5e208f9f827", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadLogisticaButton.tsx:192"}, "properties": {"repobilityId": "03cccfdf7e2697b9", "scanner": "scanner-primary", "fingerprint": "6b03c5e208f9f827", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-018c926ddf86dfc4", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadProvisionesButton.tsx:96"}, "properties": {"repobilityId": "99f82f9672f136b3", "scanner": "scanner-primary", "fingerprint": "018c926ddf86dfc4", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-50e1e3ae140a1e07", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/RazonesScore.tsx:47"}, "properties": {"repobilityId": "3a628f16206b738b", "scanner": "scanner-primary", "fingerprint": "50e1e3ae140a1e07", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ce5788eb5b30ecbe", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/Sidebar.tsx:171"}, "properties": {"repobilityId": "450176a4d82f7dad", "scanner": "scanner-primary", "fingerprint": "ce5788eb5b30ecbe", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-eaddcd167e4242d0", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadFNEButton.tsx:105"}, "properties": {"repobilityId": "b62b451767aa72bf", "scanner": "scanner-primary", "fingerprint": "eaddcd167e4242d0", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-0adfd5d6b76d5d82", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/UploadSaldosButton.tsx:89"}, "properties": {"repobilityId": "e8c0d68ee2a6713d", "scanner": "scanner-primary", "fingerprint": "0adfd5d6b76d5d82", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-91a83a3af1fdcaf5", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AsignarTareaModal.tsx:222"}, "properties": {"repobilityId": "5c2b8b6d3bc693a8", "scanner": "scanner-primary", "fingerprint": "91a83a3af1fdcaf5", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c4a8f9de9c503ec2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/AbrirCasoButton.tsx:69"}, "properties": {"repobilityId": "24ea5884d6d76c5a", "scanner": "scanner-primary", "fingerprint": "c4a8f9de9c503ec2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-555468344dcd873f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/VinDrillTable.tsx:106"}, "properties": {"repobilityId": "0c5a131229b75112", "scanner": "scanner-primary", "fingerprint": "555468344dcd873f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-cbf6e7bc716d6aa2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/CasoModal.tsx:50"}, "properties": {"repobilityId": "1e27c2627ccd1293", "scanner": "scanner-primary", "fingerprint": "cbf6e7bc716d6aa2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2af4fe682c51dfbd", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/FichaOperacionalVIN.tsx:678"}, "properties": {"repobilityId": "4e5d2c0f21d85123", "scanner": "scanner-primary", "fingerprint": "2af4fe682c51dfbd", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ea2d74763599f94d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/logistica/ColaGestionableLog.tsx:102"}, "properties": {"repobilityId": "0dac45c449750bff", "scanner": "scanner-primary", "fingerprint": "ea2d74763599f94d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-6a5d42193518246b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/FNEGrupoCard.tsx:141"}, "properties": {"repobilityId": "05083c49c491a5a1", "scanner": "scanner-primary", "fingerprint": "6a5d42193518246b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-372d696e3b2dc187", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/ProcesoQuebradoCard.tsx:116"}, "properties": {"repobilityId": "ad6e03b317fcfba0", "scanner": "scanner-primary", "fingerprint": "372d696e3b2dc187", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-92299af09ef5d7f7", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/ColaGestionableCN.tsx:162"}, "properties": {"repobilityId": "66fed719e1ea3188", "scanner": "scanner-primary", "fingerprint": "92299af09ef5d7f7", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8692e1c074eab324", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/control-de-negocio/RankingsSection.tsx:204"}, "properties": {"repobilityId": "af70220db87b2066", "scanner": "scanner-primary", "fingerprint": "8692e1c074eab324", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-1e3b97619d6f9905", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/tendencias/GraficosCapital.tsx:77"}, "properties": {"repobilityId": "15244c89fa8b8de6", "scanner": "scanner-primary", "fingerprint": "1e3b97619d6f9905", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa28a62bec2e477c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/ColaGestionableHistorico.tsx:131"}, "properties": {"repobilityId": "2a915d7daccc7056", "scanner": "scanner-primary", "fingerprint": "fa28a62bec2e477c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-7d4ff1ee2f66f838", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FunnelProcesoCerrado.tsx:389"}, "properties": {"repobilityId": "1ef66423ece76953", "scanner": "scanner-primary", "fingerprint": "7d4ff1ee2f66f838", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-bda20e6ae9ce85d3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/BacklogFacturaView.tsx:235"}, "properties": {"repobilityId": "10ac92e15c443b5f", "scanner": "scanner-primary", "fingerprint": "bda20e6ae9ce85d3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a122c2616de569ea", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EjeCumplimientoCard.tsx:66"}, "properties": {"repobilityId": "b532bcb0d6a8e6aa", "scanner": "scanner-primary", "fingerprint": "a122c2616de569ea", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c9d0779d97479830", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/CierreCumplimientoMes.tsx:198"}, "properties": {"repobilityId": "cb0b608c1e6c03c4", "scanner": "scanner-primary", "fingerprint": "c9d0779d97479830", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-69f4c23b0dd0a75f", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FunnelHitosFactura.tsx:221"}, "properties": {"repobilityId": "af61975c59dbd3bc", "scanner": "scanner-primary", "fingerprint": "69f4c23b0dd0a75f", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-2ebce2c9815d76c8", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/ProcesoSelector.tsx:65"}, "properties": {"repobilityId": "446057887f638163", "scanner": "scanner-primary", "fingerprint": "2ebce2c9815d76c8", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-dcc877ed0d471e37", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/FaltantesProcesoSection.tsx:115"}, "properties": {"repobilityId": "fb7c4ddfe601bd2a", "scanner": "scanner-primary", "fingerprint": "dcc877ed0d471e37", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa15d72b55dfbc31", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/TimelineProcesoCard.tsx:104"}, "properties": {"repobilityId": "e79ffb4111640e84", "scanner": "scanner-primary", "fingerprint": "fa15d72b55dfbc31", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-12ea4969dd335bf9", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EstadoCargaColapsible.tsx:109"}, "properties": {"repobilityId": "9738a9c2ca9e67b5", "scanner": "scanner-primary", "fingerprint": "12ea4969dd335bf9", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ca90240ac3ac2603", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/historico/EstadoCargaPanel.tsx:44"}, "properties": {"repobilityId": "907713df029ac5bc", "scanner": "scanner-primary", "fingerprint": "ca90240ac3ac2603", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-32218cbda0d747ed", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/EjeTabs.tsx:54"}, "properties": {"repobilityId": "9167f0f539d95c82", "scanner": "scanner-primary", "fingerprint": "32218cbda0d747ed", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-04c337dfd851c026", "level": "note", "message": {"text": "\"active\" state uses light bg in a dark theme \u2014 src/components/historico/ModoProcesoToggle.tsx:58"}, "properties": {"repobilityId": "1990b3f8db1f68af", "scanner": "scanner-primary", "fingerprint": "04c337dfd851c026", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.active-light-bg"]}}, {"ruleId": "scanner-ecfb717cb5ede54c", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/StockNoDisponible.tsx:68"}, "properties": {"repobilityId": "a92417a61451de06", "scanner": "scanner-primary", "fingerprint": "ecfb717cb5ede54c", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-62da977642c0dff3", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/IndicadorResumido.tsx:69"}, "properties": {"repobilityId": "b58b110c3bf1a6b9", "scanner": "scanner-primary", "fingerprint": "62da977642c0dff3", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-91e23e6abdfb918a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/ColaIndicador.tsx:368"}, "properties": {"repobilityId": "cc09290104db354b", "scanner": "scanner-primary", "fingerprint": "91e23e6abdfb918a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-ac753df185d3601a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/score-gerencial/PlanLlegarA100Banner.tsx:102"}, "properties": {"repobilityId": "bd3d6eb2df8d8b0a", "scanner": "scanner-primary", "fingerprint": "ac753df185d3601a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d7842905d86a63b2", "level": "note", "message": {"text": "React Flow edge with `label=` but no project-wide edge-label CSS override \u2014 src/lib/historico/vista-derivados.ts:1286"}, "properties": {"repobilityId": "65bdd8b3986074c5", "scanner": "scanner-primary", "fingerprint": "d7842905d86a63b2", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.edge-label.no-bg"]}}, {"ruleId": "scanner-ca79160d355d7c34", "level": "none", "message": {"text": "TODO/FIXME marker in shipping code \u2014 src/lib/selectors/razones-bloqueo.ts:28"}, "properties": {"repobilityId": "00cd56eb7cfb6aa9", "scanner": "scanner-primary", "fingerprint": "ca79160d355d7c34", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.todo-marker"]}}, {"ruleId": "scanner-d63da3583b14afc0", "level": "warning", "message": {"text": "Dockerfile runs as root: Dockerfile"}, "properties": {"repobilityId": "a2ed1bd120e507db", "scanner": "scanner-primary", "fingerprint": "d63da3583b14afc0", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-8987d6d1c30c7202", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: node:20-alpine"}, "properties": {"repobilityId": "068fbf45727eac17", "scanner": "scanner-primary", "fingerprint": "8987d6d1c30c7202", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-f954f3ec6cf33df5", "level": "warning", "message": {"text": "Dockerfile runs as root: agent/Dockerfile"}, "properties": {"repobilityId": "552d087d89262e7a", "scanner": "scanner-primary", "fingerprint": "f954f3ec6cf33df5", "layer": "hardware", "severity": "medium", "confidence": 1.0, "tags": ["security", "container"]}}, {"ruleId": "scanner-773dbb11490de160", "level": "note", "message": {"text": "Docker base image is tag-pinned but not digest-pinned: python:3.11-slim"}, "properties": {"repobilityId": "8c52107cb8740967", "scanner": "scanner-primary", "fingerprint": "773dbb11490de160", "layer": "hardware", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "docker", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "scanner-7f06ee765dc21555", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/diagnostico-conflicto-ffactura.mjs:11"}, "properties": {"repobilityId": "72ef281c8987a878", "scanner": "scanner-primary", "fingerprint": "7f06ee765dc21555", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/diagnostico-conflicto-ffactura.mjs"}, "region": {"startLine": 11}}}]}, {"ruleId": "scanner-5ec44f53a18917aa", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-cruce-vs-csv.mjs:20"}, "properties": {"repobilityId": "65515039a0c12bb2", "scanner": "scanner-primary", "fingerprint": "5ec44f53a18917aa", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-cruce-vs-csv.mjs"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-1c8682a4550f07e5", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-vista-vs-cruce.mjs:15"}, "properties": {"repobilityId": "5923bed3eaf7038d", "scanner": "scanner-primary", "fingerprint": "1c8682a4550f07e5", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-vista-vs-cruce.mjs"}, "region": {"startLine": 15}}}]}, {"ruleId": "scanner-05fe7bd909eba758", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-consolidador-actas-mono-corte.mjs:16"}, "properties": {"repobilityId": "f732ffebd392ecf5", "scanner": "scanner-primary", "fingerprint": "05fe7bd909eba758", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-consolidador-actas-mono-corte.mjs"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-e41c3f75f27c9a95", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-parser-actas-vs-csv.mjs:20"}, "properties": {"repobilityId": "b96abe3e9a826ac1", "scanner": "scanner-primary", "fingerprint": "e41c3f75f27c9a95", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-parser-actas-vs-csv.mjs"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-4189d8490e0b41a7", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-consolidador-actas-vs-csv.mjs:21"}, "properties": {"repobilityId": "343c930d83981299", "scanner": "scanner-primary", "fingerprint": "4189d8490e0b41a7", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-consolidador-actas-vs-csv.mjs"}, "region": {"startLine": 21}}}]}, {"ruleId": "scanner-a83233e9a29b47ee", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/diagnostico-conflicto-finscripcion.mjs:27"}, "properties": {"repobilityId": "fa95a44095e79cf1", "scanner": "scanner-primary", "fingerprint": "a83233e9a29b47ee", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/diagnostico-conflicto-finscripcion.mjs"}, "region": {"startLine": 27}}}]}, {"ruleId": "scanner-5574202956788116", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-consolidador-vs-csv.mjs:16"}, "properties": {"repobilityId": "649310aa69be7097", "scanner": "scanner-primary", "fingerprint": "5574202956788116", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-consolidador-vs-csv.mjs"}, "region": {"startLine": 16}}}]}, {"ruleId": "scanner-92b46083a331c7fa", "level": "warning", "message": {"text": "Insecure pattern 'node_child_process' in diag/validar-parser-roma-vs-csv.mjs:20"}, "properties": {"repobilityId": "00107bbac835e05c", "scanner": "scanner-primary", "fingerprint": "92b46083a331c7fa", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "node_child_process"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "diag/validar-parser-roma-vs-csv.mjs"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "note", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "2aee2e2d969c7c6b", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "low", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 22}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "4319262162feb627", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 25}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "8c49f82bc1fad1c1", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 33}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "745a6fb6c40aa11b", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 58}}}]}, {"ruleId": "scanner-28c4a04bd807da0c", "level": "warning", "message": {"text": "GitHub Action is tag-pinned rather than SHA-pinned"}, "properties": {"repobilityId": "18060233f7959281", "scanner": "scanner-primary", "fingerprint": "28c4a04bd807da0c", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["supply-chain", "github-actions", "pinned-dependencies"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/deploy.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "scanner-1b94ff6727bae3f0", "level": "note", "message": {"text": "Very large file: src/app/dashboard/page.tsx (2923 lines)"}, "properties": {"repobilityId": "d1018ecc2e88ff7e", "scanner": "scanner-primary", "fingerprint": "1b94ff6727bae3f0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-4ad8875fd5bedf38", "level": "note", "message": {"text": "Very large file: src/app/kia/page.tsx (1397 lines)"}, "properties": {"repobilityId": "afb3ad35edec4782", "scanner": "scanner-primary", "fingerprint": "4ad8875fd5bedf38", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-fe00d11e4a7231e2", "level": "note", "message": {"text": "Very large file: src/app/facturados-no-entregados/page.tsx (1439 lines)"}, "properties": {"repobilityId": "81df6444abc5c311", "scanner": "scanner-primary", "fingerprint": "fe00d11e4a7231e2", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-156233730a9040bf", "level": "note", "message": {"text": "Very large file: src/app/centro-accion/page.tsx (2507 lines)"}, "properties": {"repobilityId": "ab16f5db5181ec4d", "scanner": "scanner-primary", "fingerprint": "156233730a9040bf", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-b0979fb2ea31d5ab", "level": "note", "message": {"text": "Very large file: src/app/capital-trabajo/page.tsx (1365 lines)"}, "properties": {"repobilityId": "3fe70ee0ed234e3a", "scanner": "scanner-primary", "fingerprint": "b0979fb2ea31d5ab", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-a05f8b7b7b305e7f", "level": "note", "message": {"text": "Very large file: src/lib/historico/vista-derivados.ts (2428 lines)"}, "properties": {"repobilityId": "e0541fdfcd78f503", "scanner": "scanner-primary", "fingerprint": "a05f8b7b7b305e7f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-7cbd459306894940", "level": "note", "message": {"text": "Very large file: src/lib/historico/__tests__/vista-derivados.test.ts (1588 lines)"}, "properties": {"repobilityId": "8b814a90aac149a4", "scanner": "scanner-primary", "fingerprint": "7cbd459306894940", "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-8d0501dd6688c007", "level": "note", "message": {"text": "81 TODO/FIXME markers"}, "properties": {"repobilityId": "4b38c118003e07d2", "scanner": "scanner-primary", "fingerprint": "8d0501dd6688c007", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["maintenance"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "2ba9e3704685b0f2", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "9fce7138f1de9131", "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": "7ffc3dfff52cc684", "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": "928551ebc3b4b8db", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-8150b4100e15ae2e", "level": "none", "message": {"text": "Commented-code block (5 lines) in scripts/verify-gestion.mjs:1"}, "properties": {"repobilityId": "4adbb8bf4ee56192", "scanner": "scanner-primary", "fingerprint": "8150b4100e15ae2e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f69e6ee524198dd9", "level": "none", "message": {"text": "Commented-code block (11 lines) in agent/tools.py:472"}, "properties": {"repobilityId": "6476d571b21e55ac", "scanner": "scanner-primary", "fingerprint": "f69e6ee524198dd9", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-1d7f4638cd8442f6", "level": "none", "message": {"text": "Commented-code block (5 lines) in diag/redefinir-doc-listo.mjs:288"}, "properties": {"repobilityId": "70c4f7453f5333fe", "scanner": "scanner-primary", "fingerprint": "1d7f4638cd8442f6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-13ba2ff9017adff3", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/app/dashboard/page.tsx:155"}, "properties": {"repobilityId": "f57148f355766c26", "scanner": "scanner-primary", "fingerprint": "13ba2ff9017adff3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4c36f0b552ee5526", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/api/snapshot/route.ts:143"}, "properties": {"repobilityId": "8262b6c6a1a68dff", "scanner": "scanner-primary", "fingerprint": "4c36f0b552ee5526", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b1c7172e50cc5fba", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/centro-accion/page.tsx:356"}, "properties": {"repobilityId": "d49d8248e6931296", "scanner": "scanner-primary", "fingerprint": "b1c7172e50cc5fba", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-7bae4ecb3fca693d", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/tendencias/page.tsx:105"}, "properties": {"repobilityId": "7b77ebbbe4b2fcae", "scanner": "scanner-primary", "fingerprint": "7bae4ecb3fca693d", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-d72a901b0a960bc8", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/app/operaciones/control-de-negocio/page.tsx:163"}, "properties": {"repobilityId": "f6f49500552c95be", "scanner": "scanner-primary", "fingerprint": "d72a901b0a960bc8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f6a2bd3173b320c6", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/components/SnapshotHydrator.tsx:127"}, "properties": {"repobilityId": "ac4d24a359f14f59", "scanner": "scanner-primary", "fingerprint": "f6a2bd3173b320c6", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-248254e79d3cf8c3", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/lib/ventas-q1.ts:99"}, "properties": {"repobilityId": "a5742f8de6297fd2", "scanner": "scanner-primary", "fingerprint": "248254e79d3cf8c3", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-5002216c467b5247", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/types.ts:122"}, "properties": {"repobilityId": "e809e422ec63fb3d", "scanner": "scanner-primary", "fingerprint": "5002216c467b5247", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0ae98885a8951015", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/snapshot-client.ts:177"}, "properties": {"repobilityId": "2bf3440ce8027481", "scanner": "scanner-primary", "fingerprint": "0ae98885a8951015", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-95189ee1acba8465", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/parser/romia-logistica.ts:187"}, "properties": {"repobilityId": "7a0fcb032109b82e", "scanner": "scanner-primary", "fingerprint": "95189ee1acba8465", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-eb0cb735ac22a9ca", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/gestion/store.ts:178"}, "properties": {"repobilityId": "394789177b6182ce", "scanner": "scanner-primary", "fingerprint": "eb0cb735ac22a9ca", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-765d4090f48bd37e", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/gestion/types.ts:21"}, "properties": {"repobilityId": "06471598a41b1538", "scanner": "scanner-primary", "fingerprint": "765d4090f48bd37e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0429b33dc2fb2945", "level": "none", "message": {"text": "Commented-code block (8 lines) in src/lib/logistica/construir.ts:202"}, "properties": {"repobilityId": "5da519ffb4dbba10", "scanner": "scanner-primary", "fingerprint": "0429b33dc2fb2945", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-c13cb25e79f7d989", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/control-de-negocio/cn-universo.ts:127"}, "properties": {"repobilityId": "a0c8593a5b3934a9", "scanner": "scanner-primary", "fingerprint": "c13cb25e79f7d989", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-0efe11337fc6ccba", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/lib/ingesta/procesar.ts:286"}, "properties": {"repobilityId": "f9cc12bf28413233", "scanner": "scanner-primary", "fingerprint": "0efe11337fc6ccba", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-bdf7d21ada650e5f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/historico/consolidar-periodo.ts:146"}, "properties": {"repobilityId": "6d646507c67610fb", "scanner": "scanner-primary", "fingerprint": "bdf7d21ada650e5f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f9653ff5b65a981a", "level": "note", "message": {"text": "Legacy-named symbol `sgLegacy` in src/lib/historico/calcular-scores-por-dia.ts:76"}, "properties": {"repobilityId": "1cbec9c8260fec25", "scanner": "scanner-primary", "fingerprint": "f9653ff5b65a981a", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "legacy-marker", "dead-code"]}}, {"ruleId": "scanner-9fbfb402ede410d2", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/historico/persistir.ts:485"}, "properties": {"repobilityId": "f97c3bb83e02c360", "scanner": "scanner-primary", "fingerprint": "9fbfb402ede410d2", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-abb80ae06400ba07", "level": "none", "message": {"text": "Commented-code block (9 lines) in src/lib/historico/vista-derivados.ts:713"}, "properties": {"repobilityId": "d4e256d0e56b7fcf", "scanner": "scanner-primary", "fingerprint": "abb80ae06400ba07", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-017b5a70f4aefc73", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/selectors/vehiculo-unificado.ts:366"}, "properties": {"repobilityId": "41dc7ae15c075959", "scanner": "scanner-primary", "fingerprint": "017b5a70f4aefc73", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dad44d81a6bda6d4", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/selectors/usados-operacional.ts:210"}, "properties": {"repobilityId": "d651a7b265d3a4fb", "scanner": "scanner-primary", "fingerprint": "dad44d81a6bda6d4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-dee7741be46653e8", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/selectors/score-gerencial.ts:178"}, "properties": {"repobilityId": "bdd77c3d05ac4eb0", "scanner": "scanner-primary", "fingerprint": "dee7741be46653e8", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4ccee41a7bf4cc14", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/selectors/capital-trabajo-marca.ts:97"}, "properties": {"repobilityId": "4d1a9484efcf8c43", "scanner": "scanner-primary", "fingerprint": "4ccee41a7bf4cc14", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-cca15a19bf9e8711", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/lib/selectors/owner-operacional.ts:274"}, "properties": {"repobilityId": "250acd807a031454", "scanner": "scanner-primary", "fingerprint": "cca15a19bf9e8711", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-6191d9d7c7c2e73c", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/selectors/vu-en-fne.ts:141"}, "properties": {"repobilityId": "1212b355d5f0116e", "scanner": "scanner-primary", "fingerprint": "6191d9d7c7c2e73c", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-2d8f718a55c03e9a", "level": "none", "message": {"text": "Commented-code block (7 lines) in src/lib/selectors/hero-operacional.ts:120"}, "properties": {"repobilityId": "c57907324eb72423", "scanner": "scanner-primary", "fingerprint": "2d8f718a55c03e9a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-ce3502fd58613053", "level": "error", "message": {"text": "FastAPI POST `receive_webhook` without auth dependency \u2014 agent/webhook.py:54"}, "properties": {"repobilityId": "20e450066803bd24", "scanner": "scanner-primary", "fingerprint": "ce3502fd58613053", "layer": "security", "severity": "high", "confidence": 1.0, "tags": ["auth", "owasp", "auth.fastapi.unauth_mutation"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "agent/webhook.py"}, "region": {"startLine": 54}}}]}, {"ruleId": "scanner-e9a442bef1b0f3ec", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/users (src/app/usuarios/page.tsx:93)"}, "properties": {"repobilityId": "14f1f9ecee21a3bf", "scanner": "scanner-primary", "fingerprint": "e9a442bef1b0f3ec", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-9e9a67a6f9922f0f", "level": "error", "message": {"text": "Dangling fetch: POST /api/admin/users/${user.id}/reset-password (src/app/usuarios/page.tsx:168)"}, "properties": {"repobilityId": "87670d368651fd35", "scanner": "scanner-primary", "fingerprint": "9e9a67a6f9922f0f", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-83860722eb3014ea", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:236)"}, "properties": {"repobilityId": "477d50fbf60ee7ce", "scanner": "scanner-primary", "fingerprint": "83860722eb3014ea", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6b5d3387ee26b04a", "level": "error", "message": {"text": "Dangling fetch: GET /api/admin/users (src/app/usuarios/page.tsx:352)"}, "properties": {"repobilityId": "913a6dfb5a327411", "scanner": "scanner-primary", "fingerprint": "6b5d3387ee26b04a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-6819634c1e0e08c7", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:362)"}, "properties": {"repobilityId": "8867c5873bed0a00", "scanner": "scanner-primary", "fingerprint": "6819634c1e0e08c7", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-84d78200fbae88d2", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/admin/users/${user.id} (src/app/usuarios/page.tsx:376)"}, "properties": {"repobilityId": "9e7f59cd017f4efd", "scanner": "scanner-primary", "fingerprint": "84d78200fbae88d2", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-1b40a260b27e4f7e", "level": "error", "message": {"text": "Dangling fetch: POST /api/snapshots/daily (src/app/tendencias/GenerarSnapshotHoy.tsx:20)"}, "properties": {"repobilityId": "d046370148765c91", "scanner": "scanner-primary", "fingerprint": "1b40a260b27e4f7e", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-e50fc7429d0c24ec", "level": "error", "message": {"text": "Dangling fetch: GET /api/notificaciones${FILTRO_QS[filtro]} (src/app/notificaciones/page.tsx:85)"}, "properties": {"repobilityId": "e158b3f3d32fee8d", "scanner": "scanner-primary", "fingerprint": "e50fc7429d0c24ec", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-97b0184c463e9464", "level": "error", "message": {"text": "Dangling fetch: PATCH /api/notificaciones/${a.id} (src/app/notificaciones/page.tsx:111)"}, "properties": {"repobilityId": "659711ba5927eb6e", "scanner": "scanner-primary", "fingerprint": "97b0184c463e9464", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-41ddbeed8b6fa542", "level": "error", "message": {"text": "Dangling fetch: GET /api/snapshot?fuente=BASE_STOCK (src/components/Header.tsx:26)"}, "properties": {"repobilityId": "82802f6d02dbaa7e", "scanner": "scanner-primary", "fingerprint": "41ddbeed8b6fa542", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-7ebf980fdf528acf", "level": "error", "message": {"text": "Dangling fetch: GET /api/usuarios-asignables (src/components/AsignarTareaModal.tsx:111)"}, "properties": {"repobilityId": "6aad35b649b77202", "scanner": "scanner-primary", "fingerprint": "7ebf980fdf528acf", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-3d0dcb2e40c6bfcd", "level": "error", "message": {"text": "Dangling fetch: POST /api/tareas (src/components/AsignarTareaModal.tsx:174)"}, "properties": {"repobilityId": "58a31ec229945c01", "scanner": "scanner-primary", "fingerprint": "3d0dcb2e40c6bfcd", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-81af2b9e02a4881a", "level": "error", "message": {"text": "Dangling fetch: POST /api/snapshot (src/lib/snapshot-client.ts:136)"}, "properties": {"repobilityId": "9d3e9332caab7347", "scanner": "scanner-primary", "fingerprint": "81af2b9e02a4881a", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-d33e61b64af48952", "level": "error", "message": {"text": "Dangling fetch: GET /api/snapshot/active?${qs} (src/lib/snapshot-client.ts:177)"}, "properties": {"repobilityId": "d740a5fa3bfec97b", "scanner": "scanner-primary", "fingerprint": "d33e61b64af48952", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-88bc50f358844c15", "level": "error", "message": {"text": "Dangling fetch: GET /api/gestion (src/lib/gestion/store.ts:145)"}, "properties": {"repobilityId": "969955c047510640", "scanner": "scanner-primary", "fingerprint": "88bc50f358844c15", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-b1a9276e80e004b1", "level": "error", "message": {"text": "Dangling fetch: PUT /api/gestion/${encodeURIComponent(vin)} (src/lib/gestion/store.ts:178)"}, "properties": {"repobilityId": "f99a90b30c87fc08", "scanner": "scanner-primary", "fingerprint": "b1a9276e80e004b1", "layer": "api", "severity": "high", "confidence": 1.0, "tags": ["wiring", "dangling-fetch", "fetch"]}}, {"ruleId": "scanner-c251e9b16c727c7a", "level": "note", "message": {"text": "Unused endpoint: GET /webhook"}, "properties": {"repobilityId": "e9e2f41f9ce6e220", "scanner": "scanner-primary", "fingerprint": "c251e9b16c727c7a", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-0ae38010c60493f1", "level": "note", "message": {"text": "Unused endpoint: POST /webhook"}, "properties": {"repobilityId": "4a584f0540114ab8", "scanner": "scanner-primary", "fingerprint": "0ae38010c60493f1", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-36ea8bcc0eb74343", "level": "note", "message": {"text": "Unused endpoint: GET /debug/estado"}, "properties": {"repobilityId": "d4b5b4cf7780a607", "scanner": "scanner-primary", "fingerprint": "36ea8bcc0eb74343", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-5ad70b0e1d736ab9", "level": "note", "message": {"text": "Unused endpoint: GET /debug/tareas"}, "properties": {"repobilityId": "98d3da29ecb1917a", "scanner": "scanner-primary", "fingerprint": "5ad70b0e1d736ab9", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-76b98fc9e33f6933", "level": "note", "message": {"text": "Unused endpoint: GET /debug/tareas/ciclo"}, "properties": {"repobilityId": "e866d7c484c50c1a", "scanner": "scanner-primary", "fingerprint": "76b98fc9e33f6933", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}, {"ruleId": "scanner-45b1456f013f67da", "level": "note", "message": {"text": "Unused endpoint: GET /debug/user/{telefono}"}, "properties": {"repobilityId": "ec22792f5250f373", "scanner": "scanner-primary", "fingerprint": "45b1456f013f67da", "layer": "api", "severity": "low", "confidence": 1.0, "tags": ["wiring", "unused-endpoint"]}}]}]}