{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "scanner-bead75b0f9233e05", "name": "No API endpoints detected", "shortDescription": {"text": "No API endpoints detected"}, "fullDescription": {"text": "The scanner did not find FastAPI/Flask/Express/NestJS/GraphQL/gRPC routes. If this repo exposes APIs, the framework may be unsupported."}, "properties": {"scanner": "scanner-primary", "layer": "api", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d8f6ca8b958f6696", "name": "Stray `console.log` in TS/JS \u2014 scripts/gastos-obra.ts:71", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/gastos-obra.ts:71"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-4340fbd912cd603b", "name": "Stray `console.log` in TS/JS \u2014 scripts/cotizador/instanciar.ts:59", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cotizador/instanciar.ts:59"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b3cf88d0c60d2575", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/cockpit/prefetch-datos.tsx:20", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/cockpit/prefetch-datos.tsx:20"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-472ff5871788db97", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-archivados.tsx:59", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-archivados.tsx:59"}, "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-63f01906a1cd8e66", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/proyecto-galeria.tsx:170", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/proyecto-galeria.tsx:170"}, "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-42cc558d9901c47a", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-obras.tsx:173", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-obras.tsx:173"}, "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-648f1b0e534a08c4", "name": "Icon-only button without accessible name \u2014 src/components/cockpit/modulo-pendientes.tsx:146", "shortDescription": {"text": "Icon-only button without accessible name \u2014 src/components/cockpit/modulo-pendientes.tsx:146"}, "fullDescription": {"text": "A `<button>` whose only child is a single glyph or symbol needs `title=` or `aria-label=` so screen readers (and tooltips on hover) work.\n\nWhy: P3 in CHECKLIST.md \u2014 icon-only buttons skipped a title.\nRule id: fq.button.no-label"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-2a45a8e6fcca928e", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/panel.tsx:91", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/panel.tsx:91"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b2daf7826f2131e6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/seccion-proyecto.tsx:265", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/seccion-proyecto.tsx:265"}, "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-fa6f61620acde445", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-cotizaciones.tsx:77", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-cotizaciones.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-d7c35b82fd049ad2", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/orbital-obra.tsx:107", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/orbital-obra.tsx:107"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-c34ea074cbe3882d", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-actividad.tsx:92", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-actividad.tsx:92"}, "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-8cc7021d16127256", "name": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/command-bar.tsx:409", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/command-bar.tsx:409"}, "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-060ab96bb4cdedb6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/nuevo-presupuesto/nuevo-presupuesto.tsx:1199", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/nuevo-presupuesto/nuevo-presupuesto.tsx:1199"}, "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-28ae7abb0bbcd9be", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/actividad/actividad-screen.tsx:140", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/actividad/actividad-screen.tsx:140"}, "fullDescription": {"text": "A truncated value should reveal the full text on hover. Pass the full string via `title={...}` so the user can read it.\n\nWhy: P2 in CHECKLIST.md \u2014 truncate without hover-reveal.\nRule id: fq.truncate.no-title"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "info", "confidence": 1.0}}, {"id": "scanner-558bc09a430d37d6", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/archivados/archivados-screen.tsx:259", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/archivados/archivados-screen.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-a3b0b3ad371946ea", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/cashflow/obra/cashflow-obra-screen.tsx:473", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/cashflow/obra/cashflow-obra-screen.tsx:473"}, "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-e02ef23f0319a47b", "name": "`truncate` class without `title=` for hover reveal \u2014 src/app/cotizaciones/cotizaciones-screen.tsx:171", "shortDescription": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/cotizaciones/cotizaciones-screen.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-e9839c76615893fe", "name": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/cotizaciones/[id]/documento/page.tsx:90", "shortDescription": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/cotizaciones/[id]/documento/page.tsx:90"}, "fullDescription": {"text": "Open XSS surface unless the input is provably trusted. Replace with explicit JSX or sanitize via a vetted library.\n\nWhy: OWASP basics. Already partially flagged by the security analyzer.\nRule id: fq.dangerous-html"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-54cfbb5657de94c8", "name": "Possible secret in scripts/perf-cashflow.mjs", "shortDescription": {"text": "Possible secret in scripts/perf-cashflow.mjs"}, "fullDescription": {"text": "Detected pattern matching password_literal. Rotate the credential and move to a secret manager."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "critical", "confidence": 1.0}}, {"id": "scanner-76a5a766e04dd13b", "name": "Insecure pattern 'dangerous_innerhtml' in src/components/cockpit/prefetch-datos.tsx:20", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/cockpit/prefetch-datos.tsx:20"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a629f09a5ed4b420", "name": "Insecure pattern 'dangerous_innerhtml' in src/app/cotizaciones/[id]/documento/page.tsx:90", "shortDescription": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/cotizaciones/[id]/documento/page.tsx:90"}, "fullDescription": {"text": "Found a known-risky pattern (dangerous_innerhtml). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-4601e3ad3bb28677", "name": "No CI/CD pipelines detected", "shortDescription": {"text": "No CI/CD pipelines detected"}, "fullDescription": {"text": "No GitHub Actions, GitLab CI, or CircleCI configs found. Without CI you can't gate deploys on tests/lints."}, "properties": {"scanner": "scanner-primary", "layer": "cicd", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-fbb1359351dd0333", "name": "Very large file: src/app/nuevo-presupuesto/nuevo-presupuesto.tsx (1860 lines)", "shortDescription": {"text": "Very large file: src/app/nuevo-presupuesto/nuevo-presupuesto.tsx (1860 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-98986d2a047c43d0", "name": "Very large file: src/app/rentabilidad/rentabilidad-screen.tsx (1629 lines)", "shortDescription": {"text": "Very large file: src/app/rentabilidad/rentabilidad-screen.tsx (1629 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-65563061b6a6969f", "name": "Very large file: src/app/obras/[id]/gastos/gastos-screen.tsx (1517 lines)", "shortDescription": {"text": "Very large file: src/app/obras/[id]/gastos/gastos-screen.tsx (1517 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-ea3b5e389d8c9c0f", "name": "Low test-to-source ratio", "shortDescription": {"text": "Low test-to-source ratio"}, "fullDescription": {"text": "36 tests / 217 src (ratio 0.17)."}, "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-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "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 24 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 102 placeholder/mock markers across 28 source files. This often means the repo looks complete while core flows still use generated scaffolding or fake data."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-2d0c7b7ab8f8aacf", "name": "Critical user flow still appears backed by mock or placeholder data", "shortDescription": {"text": "Critical user flow still appears backed by mock or placeholder data"}, "fullDescription": {"text": "A payment/auth/admin/order/billing-style flow contains mock, fake, TODO, dummy, or placeholder markers in runtime source. In the Fable corpus this is a high-leverage completeness smell: the app can look finished while the money, identity, or tenant flow is still scaffolded."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, operator-readme. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-ea8f3013f588db25", "name": "Shallow git history limits provenance confidence", "shortDescription": {"text": "Shallow git history limits provenance confidence"}, "fullDescription": {"text": "The repository is a shallow clone. Origin/evolution analysis cannot distinguish fresh generation, imported legacy code, or long-lived human code with high confidence."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8424db9c75e04ba4", "name": "Very short observed git history", "shortDescription": {"text": "Very short observed git history"}, "fullDescription": {"text": "The repo has multiple source files but two or fewer visible commits. This is not a failure by itself, but it lowers confidence in evolution-based diagnosis."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-d8be51463f34634a", "name": "Commented-code block (6 lines) in scripts/perf-cashflow.mjs:1", "shortDescription": {"text": "Commented-code block (6 lines) in scripts/perf-cashflow.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-539c4c7e6b935e94", "name": "Network/subprocess call without timeout or try/except \u2014 daemon/jobs/jobslib.py:269", "shortDescription": {"text": "Network/subprocess call without timeout or try/except \u2014 daemon/jobs/jobslib.py:269"}, "fullDescription": {"text": "`subprocess.run(...)` here lacks both a `timeout=` arg and an enclosing try/except. This is exactly the class of bug that took down our git-clone earlier (HTTP/2 stream cancel surfaced as a fatal). Add a `timeout=` and wrap in try/except, or use a wrapper that retries."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-656c84eebd3fd4fb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cashflow-registro-rapido-modal.tsx:75", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cashflow-registro-rapido-modal.tsx:75"}, "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-e0964a09f724a346", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cashflow-item-modal.tsx:326", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cashflow-item-modal.tsx:326"}, "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-1da4e7c5efae205f", "name": "Commented-code block (5 lines) in src/components/cockpit/shader-lines.tsx:29", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/cockpit/shader-lines.tsx:29"}, "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-f1eaaa54af34ec51", "name": "Commented-code block (5 lines) in src/components/cockpit/monolito-3d.tsx:52", "shortDescription": {"text": "Commented-code block (5 lines) in src/components/cockpit/monolito-3d.tsx:52"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-b8c4cdaa14a152a1", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cockpit/command-bar.tsx:305", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cockpit/command-bar.tsx:305"}, "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-98d18b80660bb041", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/cashflow/extract-comprobante/route.ts:226", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/cashflow/extract-comprobante/route.ts:226"}, "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-441ee2c5af85539c", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/cashflow/planificar/[presupuesto_id]/planificar-cashflow-screen.ts", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/cashflow/planificar/[presupuesto_id]/planificar-cashflow-screen.tsx:142"}, "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-37ce14cf3c4f28cd", "name": "Commented-code block (6 lines) in src/app/terminal/terminal-screen.tsx:182", "shortDescription": {"text": "Commented-code block (6 lines) in src/app/terminal/terminal-screen.tsx:182"}, "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-315f34f246fefb7b", "name": "Commented-code block (5 lines) in src/lib/terminal-hilo.ts:91", "shortDescription": {"text": "Commented-code block (5 lines) in src/lib/terminal-hilo.ts:91"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-4dc29aed83231b98", "name": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/vault.ts:54", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/vault.ts:54"}, "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}}]}}, "automationDetails": {"id": "repobility/17868"}, "properties": {"repository": "ravnconstrucciones/cotizaciones", "repoUrl": "https://github.com/ravnconstrucciones/cotizaciones", "branch": "main"}, "results": [{"ruleId": "scanner-bead75b0f9233e05", "level": "none", "message": {"text": "No API endpoints detected"}, "properties": {"repobilityId": "0f8bb852027c38f8", "scanner": "scanner-primary", "fingerprint": "bead75b0f9233e05", "layer": "api", "severity": "info", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-d8f6ca8b958f6696", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/gastos-obra.ts:71"}, "properties": {"repobilityId": "a401fa69b3ca793b", "scanner": "scanner-primary", "fingerprint": "d8f6ca8b958f6696", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-4340fbd912cd603b", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 scripts/cotizador/instanciar.ts:59"}, "properties": {"repobilityId": "293c6aabb48d5fee", "scanner": "scanner-primary", "fingerprint": "4340fbd912cd603b", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-b3cf88d0c60d2575", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/components/cockpit/prefetch-datos.tsx:20"}, "properties": {"repobilityId": "6a80857d298437de", "scanner": "scanner-primary", "fingerprint": "b3cf88d0c60d2575", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-472ff5871788db97", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-archivados.tsx:59"}, "properties": {"repobilityId": "7b0ce22286e98dd3", "scanner": "scanner-primary", "fingerprint": "472ff5871788db97", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-63f01906a1cd8e66", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/proyecto-galeria.tsx:170"}, "properties": {"repobilityId": "171f85e13a66c7a9", "scanner": "scanner-primary", "fingerprint": "63f01906a1cd8e66", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-42cc558d9901c47a", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-obras.tsx:173"}, "properties": {"repobilityId": "c61891fe9874a997", "scanner": "scanner-primary", "fingerprint": "42cc558d9901c47a", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-648f1b0e534a08c4", "level": "note", "message": {"text": "Icon-only button without accessible name \u2014 src/components/cockpit/modulo-pendientes.tsx:146"}, "properties": {"repobilityId": "f5e8c9a78551b57e", "scanner": "scanner-primary", "fingerprint": "648f1b0e534a08c4", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.button.no-label"]}}, {"ruleId": "scanner-2a45a8e6fcca928e", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/panel.tsx:91"}, "properties": {"repobilityId": "4b6d8f577857ba8f", "scanner": "scanner-primary", "fingerprint": "2a45a8e6fcca928e", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-b2daf7826f2131e6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/seccion-proyecto.tsx:265"}, "properties": {"repobilityId": "b763b5e13c0b9dba", "scanner": "scanner-primary", "fingerprint": "b2daf7826f2131e6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-fa6f61620acde445", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-cotizaciones.tsx:77"}, "properties": {"repobilityId": "3135b4306022916a", "scanner": "scanner-primary", "fingerprint": "fa6f61620acde445", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-d7c35b82fd049ad2", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/orbital-obra.tsx:107"}, "properties": {"repobilityId": "c667e0eadf098796", "scanner": "scanner-primary", "fingerprint": "d7c35b82fd049ad2", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-c34ea074cbe3882d", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/modulo-actividad.tsx:92"}, "properties": {"repobilityId": "7b17393b6ae96471", "scanner": "scanner-primary", "fingerprint": "c34ea074cbe3882d", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-8cc7021d16127256", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/components/cockpit/command-bar.tsx:409"}, "properties": {"repobilityId": "7b08adc5a77e026e", "scanner": "scanner-primary", "fingerprint": "8cc7021d16127256", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-060ab96bb4cdedb6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/nuevo-presupuesto/nuevo-presupuesto.tsx:1199"}, "properties": {"repobilityId": "b02aff1b677cf3d6", "scanner": "scanner-primary", "fingerprint": "060ab96bb4cdedb6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-28ae7abb0bbcd9be", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/actividad/actividad-screen.tsx:140"}, "properties": {"repobilityId": "8c197552614e5aed", "scanner": "scanner-primary", "fingerprint": "28ae7abb0bbcd9be", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-558bc09a430d37d6", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/archivados/archivados-screen.tsx:259"}, "properties": {"repobilityId": "a4c900cad1a403ae", "scanner": "scanner-primary", "fingerprint": "558bc09a430d37d6", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-a3b0b3ad371946ea", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/cashflow/obra/cashflow-obra-screen.tsx:473"}, "properties": {"repobilityId": "5579b1ff13635338", "scanner": "scanner-primary", "fingerprint": "a3b0b3ad371946ea", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e02ef23f0319a47b", "level": "none", "message": {"text": "`truncate` class without `title=` for hover reveal \u2014 src/app/cotizaciones/cotizaciones-screen.tsx:171"}, "properties": {"repobilityId": "058041cdd373605b", "scanner": "scanner-primary", "fingerprint": "e02ef23f0319a47b", "layer": "frontend", "severity": "info", "confidence": 1.0, "tags": ["frontend-quality", "fq.truncate.no-title"]}}, {"ruleId": "scanner-e9839c76615893fe", "level": "warning", "message": {"text": "`dangerouslySetInnerHTML` used in a React component \u2014 src/app/cotizaciones/[id]/documento/page.tsx:90"}, "properties": {"repobilityId": "af19bdbf25746972", "scanner": "scanner-primary", "fingerprint": "e9839c76615893fe", "layer": "frontend", "severity": "medium", "confidence": 1.0, "tags": ["frontend-quality", "fq.dangerous-html"]}}, {"ruleId": "scanner-54cfbb5657de94c8", "level": "error", "message": {"text": "Possible secret in scripts/perf-cashflow.mjs"}, "properties": {"repobilityId": "2834fd87c1a30e5c", "scanner": "scanner-primary", "fingerprint": "54cfbb5657de94c8", "layer": "security", "severity": "critical", "confidence": 1.0, "tags": ["secrets"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/perf-cashflow.mjs"}, "region": {"startLine": 14}}}]}, {"ruleId": "scanner-76a5a766e04dd13b", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/components/cockpit/prefetch-datos.tsx:20"}, "properties": {"repobilityId": "153e844084fd08b3", "scanner": "scanner-primary", "fingerprint": "76a5a766e04dd13b", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/components/cockpit/prefetch-datos.tsx"}, "region": {"startLine": 20}}}]}, {"ruleId": "scanner-a629f09a5ed4b420", "level": "warning", "message": {"text": "Insecure pattern 'dangerous_innerhtml' in src/app/cotizaciones/[id]/documento/page.tsx:90"}, "properties": {"repobilityId": "8f1f54a82dd5b5cd", "scanner": "scanner-primary", "fingerprint": "a629f09a5ed4b420", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "dangerous_innerhtml"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/cotizaciones/[id]/documento/page.tsx"}, "region": {"startLine": 90}}}]}, {"ruleId": "scanner-4601e3ad3bb28677", "level": "warning", "message": {"text": "No CI/CD pipelines detected"}, "properties": {"repobilityId": "c3ee439bce2bc51e", "scanner": "scanner-primary", "fingerprint": "4601e3ad3bb28677", "layer": "cicd", "severity": "medium", "confidence": 1.0, "tags": ["coverage"]}}, {"ruleId": "scanner-fbb1359351dd0333", "level": "note", "message": {"text": "Very large file: src/app/nuevo-presupuesto/nuevo-presupuesto.tsx (1860 lines)"}, "properties": {"repobilityId": "a6c1f1d96a0720d6", "scanner": "scanner-primary", "fingerprint": "fbb1359351dd0333", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-98986d2a047c43d0", "level": "note", "message": {"text": "Very large file: src/app/rentabilidad/rentabilidad-screen.tsx (1629 lines)"}, "properties": {"repobilityId": "29bafa2615a620d0", "scanner": "scanner-primary", "fingerprint": "98986d2a047c43d0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-65563061b6a6969f", "level": "note", "message": {"text": "Very large file: src/app/obras/[id]/gastos/gastos-screen.tsx (1517 lines)"}, "properties": {"repobilityId": "7e07cec8e6964533", "scanner": "scanner-primary", "fingerprint": "65563061b6a6969f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-ea3b5e389d8c9c0f", "level": "note", "message": {"text": "Low test-to-source ratio"}, "properties": {"repobilityId": "ef7b2552cc00a375", "scanner": "scanner-primary", "fingerprint": "ea3b5e389d8c9c0f", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["tests"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "47586ae375b6a3d0", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "1240852c8860713b", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "10bcd5e533438282", "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": "b931d1e01bbb97ac", "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": "d290e99f922bb3c0", "scanner": "scanner-primary", "fingerprint": "2d0c7b7ab8f8aacf", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["placeholder", "mock-data", "critical-flow", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "177c39cdfee67a9b", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-ea8f3013f588db25", "level": "note", "message": {"text": "Shallow git history limits provenance confidence"}, "properties": {"repobilityId": "2828096884ddc9ef", "scanner": "scanner-primary", "fingerprint": "ea8f3013f588db25", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-8424db9c75e04ba4", "level": "none", "message": {"text": "Very short observed git history"}, "properties": {"repobilityId": "6d0a2c410f0b183b", "scanner": "scanner-primary", "fingerprint": "8424db9c75e04ba4", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["provenance", "git-history", "generated-repo-pattern"]}}, {"ruleId": "scanner-d8be51463f34634a", "level": "none", "message": {"text": "Commented-code block (6 lines) in scripts/perf-cashflow.mjs:1"}, "properties": {"repobilityId": "4b879959a3c5bd3c", "scanner": "scanner-primary", "fingerprint": "d8be51463f34634a", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-539c4c7e6b935e94", "level": "warning", "message": {"text": "Network/subprocess call without timeout or try/except \u2014 daemon/jobs/jobslib.py:269"}, "properties": {"repobilityId": "2644071ea0624820", "scanner": "scanner-primary", "fingerprint": "539c4c7e6b935e94", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-656c84eebd3fd4fb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cashflow-registro-rapido-modal.tsx:75"}, "properties": {"repobilityId": "f10e7eada19a1dce", "scanner": "scanner-primary", "fingerprint": "656c84eebd3fd4fb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-e0964a09f724a346", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cashflow-item-modal.tsx:326"}, "properties": {"repobilityId": "a7b9406fe58c5838", "scanner": "scanner-primary", "fingerprint": "e0964a09f724a346", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-1da4e7c5efae205f", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/cockpit/shader-lines.tsx:29"}, "properties": {"repobilityId": "2b0c4847d5c8a822", "scanner": "scanner-primary", "fingerprint": "1da4e7c5efae205f", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-f1eaaa54af34ec51", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/components/cockpit/monolito-3d.tsx:52"}, "properties": {"repobilityId": "e462060df6df6429", "scanner": "scanner-primary", "fingerprint": "f1eaaa54af34ec51", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-b8c4cdaa14a152a1", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/components/cockpit/command-bar.tsx:305"}, "properties": {"repobilityId": "06a11d0475da5d12", "scanner": "scanner-primary", "fingerprint": "b8c4cdaa14a152a1", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-98d18b80660bb041", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/api/cashflow/extract-comprobante/route.ts:226"}, "properties": {"repobilityId": "ec49dcbe6e732d66", "scanner": "scanner-primary", "fingerprint": "98d18b80660bb041", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-441ee2c5af85539c", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/app/cashflow/planificar/[presupuesto_id]/planificar-cashflow-screen.tsx:142"}, "properties": {"repobilityId": "2491a721c4b69888", "scanner": "scanner-primary", "fingerprint": "441ee2c5af85539c", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-37ce14cf3c4f28cd", "level": "none", "message": {"text": "Commented-code block (6 lines) in src/app/terminal/terminal-screen.tsx:182"}, "properties": {"repobilityId": "10f5deabb5480af3", "scanner": "scanner-primary", "fingerprint": "37ce14cf3c4f28cd", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-315f34f246fefb7b", "level": "none", "message": {"text": "Commented-code block (5 lines) in src/lib/terminal-hilo.ts:91"}, "properties": {"repobilityId": "afa6df97267cd436", "scanner": "scanner-primary", "fingerprint": "315f34f246fefb7b", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-4dc29aed83231b98", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 src/lib/vault.ts:54"}, "properties": {"repobilityId": "f9637b54bb826773", "scanner": "scanner-primary", "fingerprint": "4dc29aed83231b98", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}]}]}