Skip to content

Reports de Test Run

Leia no seu idioma: English · Português · Español

Status do escopo (pós-congelamento de escopo 2026-05-10) — Ver ARCHITECTURE.md para os 37 MÓDULOs canônicos + 7 Test Kinds + arquitetura de safety DOM/CPOS/PIE-PA. ADRs 0014, 0019-0025 cobrem adições pós-Freeze.

Status: Fase 1 entregue — report HTML print-styled com JSON estruturado. Fases 2–5 adicionam PDF server-rendered, anexos de inventário DUT, assinatura Cosign e comparação N-runs. Veja platform/test-plans/catalog.yaml para o lado de test plan.

Por que Reports

Spirent CyberFlood e Ixia BreakingPoint ambos entregam reports proprietários — PDFs caixa-preta que operadores confiam porque vieram de um fornecedor pago. Este projeto entrega um sistema de report aberto e determinístico, projetado para ser demonstravelmente mais forte que aqueles:

Capacidade Spirent / Ixia Este projeto
Capa com identidade do run
Identificador de plano estável entre engagements ✅ (preso ao fornecedor) ✅ (CAP-FIND-KNEE-30M, git-versionado)
Hash do plan-snapshot provando que parâmetros não foram editados pós-run
Hash do conteúdo do report para chain-of-custody forense ✅ (Fase 1)
Inventário do DUT (NGFW + switch) + config sanitizada como anexo 🟡 Fase 3 — Nexus 9000 + NGFW
Evidência independente do modo TLS-decrypt (cert do issuer) ✅ (probe na fiação da Fase 3)
Assinatura criptográfica no PDF 🟡 Fase 4 — Cosign
Report de comparação N-runs (últimos 5 runs lado a lado) ⚠️ add-on pago 🟡 Fase 5
Reprodutibilidade — replay de um report publicado contra seu próprio NGFW 🟡 Fase 5 — modo replay
Aviso de licença em toda página ✅ Fase 1

Onze diferenciadores forenses

A tabela de comparação acima cobre a fundação. Além dela, o sistema de report adiciona onze capacidades concretas que miram mais alto que as alternativas fechadas e pagas. Duas já foram entregues; nove estão escopadas nas Fases 2–5.

# Capacidade Status
1 Automação de análise causal — correlação topology-aware produz sentenças "fato → consequência → recomendação" ✅ entregue em #177
2 Timeline do modo TLS Decrypt — probe independente de issuer-cert como ground-truth; alerta TLSDecryptModeChanged invalida automaticamente resultados que cruzam um flip de estado ✅ entregue em #180
3 Prova de validade do test-bed — verdict por janela (e.g. "resultados na janela 14:00–14:23 estão limpos; 14:23–14:31 estão contaminados por saturação do UCS-2") 🟡 Fase 5
4 Breakdown de latência por hop — handshake agent→NGFW / handshake NGFW→persona / TTFB / object load em colunas separadas, não só end-to-end 🟡 Fase 5
5 Análise por archetype — summary separado por skin / mock / har-replay / real-app — cada archetype exercita um path diferente do NGFW 🟡 Fase 5
6 Manifesto de reprodutibilidade — git SHA, image digests SHA-256, sysctls aplicados em cada UCS, deployment mode, fingerprint da config do NGFW — a receita completa 🟡 Fase 4
7 PDF assinado criptograficamente — Cosign keyless via signing key do cluster; entrada Rekor/Sigstore opcional como log de transparência 🟡 Fase 4
8 Intervalos de confiança por seção — toda métrica vem com CI baseado em sample size, não só a média 🟡 Fase 5
9 Atribuição detalhada de falhas — e.g. "47 dos 12.847 erros foram NGFW timeout, 12 foram TLS handshake fail, 8 foram conntrack overflow do test-bed" 🟡 Fase 5
10 Snapshot de replay — link "open in viewer" abre dashboards Grafana como estavam no momento do run (Prometheus state congelado) 🟡 Fase 5
11 Narrativa em prosa de grau forense — exec summary em prosa que navega resultados com confidence levels — não só um dump de tabela 🟡 Fase 5

Fase 1 — o que foi entregue

A API de dados

GET /api/test-runs/{executionId}/report.json

Retorna o 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 e X-License carregam o mesmo hash + license-id para tooling downstream.

A página de print

GET /runs/{executionId}/report

Uma página HTML server-rendered, com estilo de print, contendo:

  • Capa — run id, plano, datas, badge SLO, badge de licença, SHA-256 do report + SHA-256 do plan-snapshot
  • Licensing & Use Restrictions — texto completo de audiência + campo de uso em EN / PT-BR / ES na página imediatamente após a capa
  • Executive Summary — KPIs agregados, SLO pass/fail com percentual de queima do budget
  • Test Plan Configuration — tabela de parâmetros + timeline de fases
  • Anexos — placeholders para Fase 3 (inventário Nexus + NGFW)
  • Footer de licença — fixado em toda página impressa (o operador não consegue retirá-lo sem re-renderizar)

A página renderiza com margens @page A4 portrait e footers com contador de páginas. Browsers podem "Salvar como PDF" hoje; Fase 2 troca por Puppeteer para renderização determinística no servidor.

Hashes forenses já presentes na Fase 1

Hash A que se compromete
reportSha256 Payload JSON canônico completo — prova que dados do report não foram adulterados
planSnapshotSha256 Parâmetros do plano congelados no início do run — prova que o plano não foi editado durante o run
annex.sha256 (por anexo) Corpo de cada anexo — Fase 3 usa para attestação de config Nexus/NGFW

Um revisor que suspeita de adulteração do PDF pode:

  1. Baixar o JSON ReportData original via API
  2. Recomputar SHA-256 do JSON canônico
  3. Comparar com o valor impresso na capa

Se baterem — o report é autêntico. Fase 4 adiciona Cosign por cima para tornar isso trivialmente verificável.

O que Fases 2–5 adicionam

Fase Adiciona
2 Puppeteer renderiza esta página server-side → /api/test-runs/{id}/report.pdf retorna PDF real
3 DUT Inventory Probe popula Anexo B (Nexus 9000) + Anexo C (NGFW) + Anexo D (chassi UCS) com modelo real, S/N, running-config sanitizada. Parcialmente entregue: a fundação DUT API + 4 vendor adapters (Cisco FTD, Nexus, UCS CIMC Redfish, FortiGate) e a infraestrutura de snapshot/hash já estão vivas desde v4.0.0 (#199, #210); ligar os snapshots aos Anexos B/C/D do report é a peça que falta (PR-D no roadmap v4.1)
4 Assinatura Cosign keyless OIDC no PDF + embed de Grafana state snapshot (os dashboards reais como estavam durante o run)
5 Report de comparação N-runs (últimos 5 runs do mesmo plano, p50/p95/p99 lado a lado) + modo replay (baixa a versão do catálogo + snapshot do plano para reproduzir a load shape em outro lugar)

Workflow do operador

  1. Escolha um plano do catálogo, dispare um run via Dashboard
  2. Run completa — linha em test_run_executions recebe endedAt + outcome
  3. Abra /runs/{executionId}/report no browser
  4. Print → Save as PDF (Fase 1) — ou aguarde Fase 2 e baixe o PDF assinado direto
  5. Distribua o PDF para partes autorizadas; o footer de licença + capa lembram a política de audiência

Comparado com alternativas comerciais

O report do Ixia BreakingPoint é um PDF de formato fechado renderizado por um engine fechado; o operador precisa confiar no vendor que os números não foram massageados. Este sistema inverte isso:

  • Os dados são um shape JSON versionado (ReportData) — qualquer um pode re-parsear
  • O PDF é uma renderização de print de uma página HTML — qualquer um pode re-renderizar
  • O plano é um YAML git-versionado — qualquer um pode confirmar o que era pra rodar
  • A config real do equipamento sob teste fica embarcada como anexo com hash (Fase 3)
  • O PDF será assinado criptograficamente (Fase 4) — qualquer um pode verificar a procedência

Tudo isso permanecendo dentro da política de audiência da licença.

Relacionados