Skip to content

[gap/feature] Coverage attestation — declared-sources vs reached (o negative-space que nenhum concorrente prova) #1169

Description

@FabioLeitao

O gap que resistiu à verificação (checado no repo antes de afirmar)

Verifiquei: o --diff (#521) está completo, e o PLAN_SCAN_RUN_MANIFEST já mede columns_sampled vs columns_skipped + reasons. Isso é coverage do espaço conhecido (das colunas que o Boar achou nas fontes conectadas, quantas amostrou). O que não existe e é o diferencial: coverage do espaço declarado vs. alcançado — a pergunta que assombra todo auditor LGPD: "e as fontes que você NÃO viu? como sabe que viu todas?"

A ideia (simples, e a doutrina anti-overclaim virada feature)

Um input --expected-sources <manifest> onde o operador declara o inventário esperado ("meus sistemas são estes 12"). O Boar cruza com o que efetivamente alcançou e emite um coverage attestation assinado:

  • declarado: 12 · alcançado: 10 · não-alcançado: 2 (X = sem credencial · Y = fora da rede)
  • e o Boar NÃO afirma nada sobre as 2 não-alcançadas (o negative-space explícito).

Transforma "escaneei tudo, confie em mim" (o que todo concorrente entrega, e é inútil pro auditor) em "escaneei 83% do declarado, eis os 17% que não alcancei e por quê" (auditável, honesto, defensável).

Por que é diferencial (cabe no jeitinho)

  • É a doutrina anti-overclaim aplicada ao próprio escopo do scanner — o scanner que se recusa a superestimar a própria cobertura.
  • BigID/Securiti nunca fariam (coverage-honesto expõe limitação); o Boar ganha por expor.
  • Simples: um set difference assinado. Cabe no min-spec, offline, determinístico.
  • Fecha venda com CISO sério — é a honestidade que compra confiança.

Delta vs. o que já existe (não duplica)

  • PLAN_SCAN_RUN_MANIFEST: sampled-vs-skipped dentro das fontes alcançadas. ← existe.
  • Este: declared-vs-reached no nível de FONTE (o antes: você chegou em todas as fontes?). ← novo.
  • Reusa config_hash, run_id, o padrão de "campo vazio explícito nunca ausente" do run-manifest.

Rascunho detalhado (MD pronto pra incluir como housekeeping)

Spec completa proposta em docs/plans/PLAN_COVERAGE_ATTESTATION.md — entregue pelo operador na sessão de auditoria (rascunho; operador ratifica, Cursor materializa). Slices, schema, invariante de honestidade e critérios de aceite no MD.

Slices (resumo)

  • Slice A — --expected-sources sources.yaml (declaração: id + tipo + label por fonte).
  • Slice B — cruzamento com connectors realmente usados/alcançados → _Coverage sheet + JSON.
  • Slice C — assinatura Ed25519 do coverage record + config_hash.
  • Slice D — invariante: fonte não-alcançada gera entrada explícita com reason, e zero finding inferido sobre ela.

Alinha: ADR-0037 (self-audit log), ADR-0048 (taxonomy), ADR-0049 (no brittle mitigations). Liga run-manifest + tidy-tortoise#8 (o coverage entra no evidence-pack).

— claude.ai · Auditor R.O. externo (steering/altitude) · Sonnet 5 · A.I.I.D.C.O.B.P.P. v1.4

Activity

  1. FabioLeitao commented on Jul 12, 2026

    @FabioLeitao
    CollaboratorAuthor

    Extension from the 07-12 strategy review — "Coverage Ledger". This coverage-attestation could productize into a per-report Coverage Ledger that gives every target/column an explicit posture:

    SCANNED / PARTIALLY SCANNED / FAILED / UNSUPPORTED / EXCLUDED BY POLICY / NOT IN SCOPE / NO FINDINGS OBSERVED

    Rationale: stops "zero findings" from being read as "zero risk" — materializes the Auditing-the-Auditor ethos and directly reinforces the #1194 class (a sampling failure must be visible, never silent). Example:

    Target: Oracle-Finance | tables 840 | columns eligible 13,420 | sampled 13,396 | sampling failures 24 | unsupported datatypes 7 | coverage: PARTIAL
    

    (Filed by Claude Code — RO auditor.)

  2. self-assigned this
    on Aug 20, 2026
  3. added this to the v1.8.4 milestone on Aug 29, 2026
  4. FabioLeitao commented on Sep 30, 2026

    @FabioLeitao
    CollaboratorAuthor

    Irmão do coverage attestation: o "atestado de calibração" do instrumento (30/set)

    O coverage attestation responde "quais fontes declaradas eu alcancei". Falta a pergunta gêmea do auditor: "o instrumento estava funcionando quando varreu?"

    Proposta (recomendatório): o mesmo atestado assinado carregaria (a) a identidade da pilha de detecção (regex e overrides, hash dos termos de ML, modelo DL com revisão e sha256: ver #1451, achado 4) e (b) o resultado de um canário sintético rodado com essa pilha no início da corrida (reusa os dados sintéticos do --demo/fixtures): "esperado N achados, obtido N", ou falha nomeada.

    O que isso pega: o modo de falha que hoje é silencioso. Verifiquei em core/detector.py que o fuzzy de nome de coluna só liga se fuzzy_column_match estiver pedido e o rapidfuzz importar (_fuzzy_enabled = requested and available), e a #1451 documenta o mesmo padrão para o DL: detector opcional indisponível e o scan termina normal. É a doutrina anti-overclaim aplicada ao próprio detector.

    Delta vs o que existe: --check-extras (#1401) é inventário de build, não teste em runtime.

    Empréstimo antes de construir: a assinatura pode vir do Homing Robin (atestação Ed25519 offline-first, air-gap-first) em vez de código novo no Boar. Não li a API dele; é mapa de papéis.

    🤖 Claude (Opus 4.8, T14, auditor RO). Tom recomendatório; nada implementado.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions