Reportes de Test Run¶
Lee en tu idioma: English · Português · Español
Estado del alcance (post-congelación de alcance 2026-05-10) — Ver ARCHITECTURE.md para los 37 MÓDULOs canónicos + 7 Test Kinds + arquitectura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cubren adiciones post-Freeze.
Estado: Fase 1 entregada — reporte HTML print-styled con JSON estructurado. Fases 2–5 añaden PDF server-rendered, anexos de inventario DUT, firma Cosign y comparación N-runs. Ver
platform/test-plans/catalog.yamlpara el lado de test plan.
Por qué Reportes¶
Spirent CyberFlood e Ixia BreakingPoint ambos entregan reportes propietarios — PDFs caja-negra que operadores confían porque vinieron de un vendor pago. Este proyecto entrega un sistema de reporte abierto y determinístico, diseñado para ser demostrablemente más fuerte que esos:
| Capacidad | Spirent / Ixia | Este proyecto |
|---|---|---|
| Portada con identidad del run | ✅ | ✅ |
| Identificador de plan estable entre engagements | ✅ (vendor-locked) | ✅ (CAP-FIND-KNEE-30M, git-versionado) |
| Hash del plan-snapshot probando que parámetros no fueron editados post-run | ❌ | ✅ |
| Hash del contenido del reporte para chain-of-custody forense | ❌ | ✅ (Fase 1) |
| Inventario del DUT (NGFW + switch) + config saneada como anexo | ❌ | 🟡 Fase 3 — Nexus 9000 + NGFW |
| Evidencia independiente del modo TLS-decrypt (cert del issuer) | ❌ | ✅ (probe en cableado de Fase 3) |
| Firma criptográfica en el PDF | ❌ | 🟡 Fase 4 — Cosign |
| Reporte de comparación N-runs (últimos 5 runs lado a lado) | ⚠️ add-on pago | 🟡 Fase 5 |
| Reproducibilidad — replay de un reporte publicado contra tu propio NGFW | ❌ | 🟡 Fase 5 — modo replay |
| Aviso de licencia en cada página | ❌ | ✅ Fase 1 |
Once diferenciadores forenses¶
La tabla de comparación arriba cubre la base. Más allá de eso, el sistema de reporte agrega once capacidades concretas que apuntan más alto que las alternativas cerradas y pagas. Dos ya se entregaron; nueve están enmarcadas en las Fases 2–5.
| # | Capacidad | Estado |
|---|---|---|
| 1 | Automatización de análisis causal — correlación topology-aware produce sentencias "hecho → consecuencia → recomendación" | ✅ entregado en #177 |
| 2 | Timeline del modo TLS Decrypt — probe independiente de issuer-cert como ground-truth; alerta TLSDecryptModeChanged invalida automáticamente resultados que cruzan un flip de estado |
✅ entregado en #180 |
| 3 | Prueba de validez del test-bed — verdict por ventana (e.g. "resultados en ventana 14:00–14:23 están limpios; 14:23–14:31 contaminados por saturación de UCS-2") | 🟡 Fase 5 |
| 4 | Breakdown de latencia por hop — handshake agent→NGFW / handshake NGFW→persona / TTFB / object load en columnas separadas, no solo end-to-end | 🟡 Fase 5 |
| 5 | Análisis por archetype — summary separado por skin / mock / har-replay / real-app — cada archetype ejercita un path diferente del NGFW | 🟡 Fase 5 |
| 6 | Manifiesto de reproducibilidad — git SHA, image digests SHA-256, sysctls aplicados por UCS, deployment mode, fingerprint de la config del NGFW — la receta completa | 🟡 Fase 4 |
| 7 | PDF firmado criptográficamente — Cosign keyless vía signing key del cluster; entrada Rekor/Sigstore opcional como log de transparencia | 🟡 Fase 4 |
| 8 | Intervalos de confianza por sección — toda métrica viene con CI basado en sample size, no solo la media | 🟡 Fase 5 |
| 9 | Atribución detallada de fallas — e.g. "47 de 12.847 errores fueron NGFW timeout, 12 fueron TLS handshake fail, 8 fueron conntrack overflow del test-bed" | 🟡 Fase 5 |
| 10 | Snapshot de replay — link "open in viewer" abre dashboards Grafana como estaban en el momento del run (Prometheus state congelado) | 🟡 Fase 5 |
| 11 | Narrativa en prosa de grado forense — exec summary en prosa que navega resultados con confidence levels — no solo un dump de tabla | 🟡 Fase 5 |
Fase 1 — qué se entregó¶
La API de datos¶
GET /api/test-runs/{executionId}/report.json
Retorna el shape canónico ReportData:
{
"version": 1,
"generatedAt": "2026-05-06T14:35:00.000Z",
"reportSha256": "<hex 64 chars>",
"meta": {
"runId": "...",
"executionId": "...",
"planIdentifier": "CAP-FIND-KNEE-30M",
"planDisplayName": "Capacity — Find the knee (30 min)",
"planCatalogVersion": 1,
"planSnapshotSha256": "<hex 64 chars>",
"durationS": 1800,
"startedAt": "...",
"endedAt": "...",
"outcome": "..."
},
"license": { "id": "LicenseRef-PolyForm-Noncommercial-1.0.0-with-Appendix-A", ... },
"plan": { "identifier": "...", "phases": [...], ... },
"topology": { "deploymentMode": "tri-node", "ucsCount": 3, ... },
"tlsDecrypt": { "activeAtStart": "on", "activeAtEnd": "on", ... },
"results": { "aggregate": { "p50_ms": 142, "p95_ms": 380, "p99_ms": 487, ... } },
"slo": { "targetP99Ms": 500, "observedP99Ms": 487, "pass": true, ... },
"annexes": [{ "id": "annex-b-nexus", "title": "...", "sha256": "...", "body": "..." }, ...]
}
Headers X-Report-Sha256 y X-License cargan el mismo hash + license-id para tooling downstream.
La página de print¶
GET /runs/{executionId}/report
Una página HTML server-rendered, con estilo de print, conteniendo:
- Portada — run id, plan, fechas, badge SLO, badge de licencia, SHA-256 del reporte + SHA-256 del plan-snapshot
- Licensing & Use Restrictions — texto completo de audiencia + campo de uso en EN / PT-BR / ES en la página inmediatamente después de la portada
- Executive Summary — KPIs agregados, SLO pass/fail con porcentaje de quema del budget
- Test Plan Configuration — tabla de parámetros + timeline de fases
- Anexos — placeholders para Fase 3 (inventario Nexus + NGFW)
- Footer de licencia — fijado en cada página impresa (el operador no puede retirarlo sin re-renderizar)
La página renderiza con márgenes @page A4 portrait y footers con contador de páginas. Browsers pueden "Guardar como PDF" hoy; Fase 2 cambia por Puppeteer para renderización determinística en el servidor.
Hashes forenses ya presentes en Fase 1¶
| Hash | A qué se compromete |
|---|---|
reportSha256 |
Payload JSON canónico completo — prueba que datos del reporte no fueron manipulados |
planSnapshotSha256 |
Parámetros del plan congelados al inicio del run — prueba que el plan no fue editado durante el run |
annex.sha256 (por anexo) |
Cuerpo de cada anexo — Fase 3 lo usa para atestación de config Nexus/NGFW |
Un revisor que sospecha manipulación del PDF puede:
- Bajar el JSON ReportData original vía API
- Recomputar SHA-256 del JSON canónico
- Comparar con el valor impreso en la portada
Si coinciden — el reporte es auténtico. Fase 4 añade Cosign por encima para hacer esto trivialmente verificable.
Lo que Fases 2–5 añaden¶
| Fase | Añade |
|---|---|
| 2 | Puppeteer renderiza esta página server-side → /api/test-runs/{id}/report.pdf retorna PDF real |
| 3 | DUT Inventory Probe puebla Anexo B (Nexus 9000) + Anexo C (NGFW) + Anexo D (chasis UCS) con modelo real, S/N, running-config saneada. Parcialmente entregado: la fundación DUT API + 4 vendor adapters (Cisco FTD, Nexus, UCS CIMC Redfish, FortiGate) y la infraestructura de snapshot/hash ya están vivas desde v4.0.0 (#199, #210); conectar los snapshots a los Anexos B/C/D del reporte es la pieza que falta (PR-D en el roadmap v4.1) |
| 4 | Firma Cosign keyless OIDC en el PDF + embed de Grafana state snapshot (los dashboards reales como estaban durante el run) |
| 5 | Reporte de comparación N-runs (últimos 5 runs del mismo plan, p50/p95/p99 lado a lado) + modo replay (baja la versión del catálogo + snapshot del plan para reproducir la load shape en otro lugar) |
Workflow del operador¶
- Elige un plan del catálogo, dispara un run vía Dashboard
- Run completa — fila en
test_run_executionsrecibeendedAt+outcome - Abre
/runs/{executionId}/reporten el browser - Print → Save as PDF (Fase 1) — o espera Fase 2 y baja el PDF firmado directo
- Distribuye el PDF a partes autorizadas; el footer de licencia + portada recuerdan la política de audiencia
Comparado con alternativas comerciales¶
El reporte del Ixia BreakingPoint es un PDF de formato cerrado renderizado por un engine cerrado; el operador necesita confiar en el vendor que los números no fueron masajeados. Este sistema invierte eso:
- Los datos son un shape JSON versionado (
ReportData) — cualquiera puede re-parsearlo - El PDF es una renderización de print de una página HTML — cualquiera puede re-renderizarlo
- El plan es un YAML git-versionado — cualquiera puede confirmar lo que se suponía debía correr
- La config real del equipo bajo prueba queda embebida como anexo con hash (Fase 3)
- El PDF será firmado criptográficamente (Fase 4) — cualquiera puede verificar la procedencia
Todo esto permaneciendo dentro de la política de audiencia de la licencia.
Relacionados¶
TEST_PLANS.es.md— los 15 planes del catálogo cuyos runs alimentan este reporteTLS_DECRYPT_MODE_VERIFICATION.es.md— probe independiente de issuer usado por el Anexo B/CMONITORING_TEST_VALIDITY.es.md— alertas que dicen "el test-bed en sí estaba saludable"USAGE_POLICY.es.md— restricciones de audiencia explicadas