Skip to content

[feature][P2] Volume Ledger — metadata-only data-volume tally, opt-in, foundation for bestiary volume-based billing #1756

Description

@FabioLeitao

Contexto / motivação

Discussão privada (operador, 2026-08-24): a escada de tiers do Boar hoje precifica por
footprint×paralelismo (docs/adr/ADR-0027, PLAN_PRODUCT_TIERS_AND_OPEN_CORE.md), não por
volume — decisão deliberada. Mas os demais produtos do bestiário (não neste repo) podem querer
precificar por volume manifestado (evento/grant/operação), e o Boar é o único componente que
já enumera as fontes primeiro. Esta issue pede só a infraestrutura de medição e exposição do
volume — não decide se o Boar cobra por ela. Se a decisão for não cobrar, o dado fica exposto e
não-usado (fica livre).

O que já existe (verificado agora, base pra não duplicar)

  • core/database.py + docs/adr/ADR-0051-incremental-filesystem-scan-file-identity-fingerprint.md
    (Phase 1 do docs/plans/PLAN_INCREMENTAL_SCAN_IDEMPOTENCY.md, já no código): toda
    FilesystemFinding grava source_size (bytes, via Path.stat()) — não precisa de nova coleta,
    é stat(), não leitura de conteúdo.
  • connectors/sql_table_row_estimate.py (já no código): estimate_table_rows() — estimativa
    de linhas só por catálogo (pg_class.reltuples / sys.partitions / all_tables.num_rows /
    information_schema.tables.table_rows), Postgres/MSSQL/Oracle/MySQL/MariaDB, sem COUNT(*)
    na heap
    . Hoje só orienta estratégia de sampling — não expõe tamanho em bytes, não vira
    resultado de relatório.

Pedido

  1. Byte-size por catálogo, mesmos 5 dialetos, mesmo padrão sql_table_row_estimate.py
    (módulo novo ou extensão do mesmo, ex. estimate_table_bytes()):
    • Postgres: pg_total_relation_size(oid) (dados+índices)
    • MSSQL: sys.dm_db_partition_stats (soma de used_page_count * 8192)
    • Oracle: DBA_SEGMENTS/USER_SEGMENTS (bytes)
    • MySQL/MariaDB: information_schema.tables.DATA_LENGTH + INDEX_LENGTH
    • Catálogo-only, sem tocar linha — mesmo princípio de docs/GLOSSARY.md (metadata-only).
  2. Uma estrutura de saída nova (nome sugerido: Volume Ledger — evitar "manifest", já
    sobrecarregado no repo: report/scan_evidence.py, report/evidence_collector.py,
    core/licensing/guard.py, integridade de release, plugin SDK todos já usam "manifest" pra
    coisas diferentes) — por target/fonte: total_bytes_approx, total_objects_or_rows_approx,
    method (stat | catalog | unavailable), computed_at. Local natural: par de
    report/scan_evidence.py/report/evidence_collector.py, ou seção nova no --export-audit-trail
    (core/audit_export.py).
  3. Opt-in explícito, default off (ex. report.volume_ledger: false) — zero mudança de
    comportamento pra quem não ligar. Sem enforcement/billing neste repo — só medição+exposição.
  4. Documentar explicitamente no plano: este componente é pensado como insumo pros demais
    produtos do bestiário
    (fora deste repo) decidirem billing por volume — o Boar em si
    permanece na métrica de footprint×paralelismo já ratificada, a menos que decisão futura mude
    isso.

Critérios de aceite

  • Criar docs/plans/PLAN_VOLUME_LEDGER.md com <!-- plans-hub-summary: ... -->.
  • Executar python scripts/plans_hub_sync.py --write.
  • Adicionar entry em docs/plans/PLANS_TODO.md.
  • estimate_table_bytes() (ou equivalente) cobrindo os 5 dialetos já suportados por
    estimate_table_rows(), mesmo padrão de erro (None silencioso, nunca exceção derruba scan).
  • Volume Ledger desligado por padrão; teste cobrindo comportamento idêntico ao atual quando
    desligado.
  • Teste cobrindo soma de source_size por target (filesystem) e byte-estimate por
    dialeto (DB), incluindo o caso "dialeto sem estimador" (retorna None, não quebra).
  • docs/REPORTS_AND_COMPLIANCE_OUTPUTS.md (+ pt_BR) documentando o novo campo/flag.

Triado e proposto — Claude (Sonnet 5) · auditor externo (READONLY, só gh issue create). Origem:
conversa privada de arquitetura/pricing com o operador, 2026-08-24 — não é achado de segurança.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions