Otimização da procedência: roadmap técnico
A procedência do Futuros hoje é derivável: o deep link é reconstruído do citation_id, a bateria de gates do prebuild (rastreabilidade, deep links, citações, pontuações, procedência, catálogo, API — mais a suíte completa de testes) rejeita qualquer número sem rastro, e o recibo do fundo fiduciário é um hash reprodutível sobre um corpo canônico (Procedência e citações, O pipeline de dados). Esta página documenta a próxima fronteira: passar de "cada número tem sua fonte" para "cada número carrega uma prova de origem verificável por máquina, que um terceiro pode conferir sem confiar em nós".
Tudo o que segue é roadmap, não capacidade em produção, salvo onde marcado o contrário. A ordem é deliberada: cada fase reutiliza costuras que já existem no código (citation_id, stableStringify, receipt_hash, chain_anchor, refresh-meta.json, os gates check-*), de modo que nenhuma fase exige uma reescrita.
O modelo-alvo: quatro propriedades
Um número com procedência otimizada satisfaz quatro propriedades independentes, cada uma com seu mecanismo:
| Propriedade | Pergunta que responde | Mecanismo |
|---|---|---|
| Integridade | Estes bytes são os que foram ingeridos? | Endereçamento por conteúdo (SHA-256) das respostas upstream |
| Autenticidade | Quem produziu este artefato? | Assinaturas Ed25519 sobre corpos canônicos + atestações de build |
| Reprodutibilidade | Posso recomputá-lo e obter o mesmo? | Bake hermético e determinista, insumos fixados por digest |
| Transparência | A história pôde ser reescrita depois? | Log append-only estilo Merkle com ancoragem externa periódica |
A disciplina atual (citações deterministas + gates de build) dá integridade interna. As fases seguintes a tornam verificável de fora.
Fase A — Camada de aquisição endereçada por conteúdo
Hoje a ingestão escreve células derivadas; os bytes crus da resposta upstream são descartados. Isso torna impossível re-auditar uma transformação depois do fato: se o Banco Mundial revisa uma série, não podemos provar qual versão vimos.
O desenho: cada fetch de adaptador persiste sua resposta crua como um blob endereçado por conteúdo:
snapshots/
sha256/ab/cd/abcd…ef # bytes crus da resposta (gzip)
manifests/wb-sp-dyn-le00-in-2026-07-30.jsonO manifesto de fetch registra { url, method, request_headers_relevantes, etag, last_modified, fetched_at, digest, adapter, source_key }. Cada célula de parameter-cache/ ganha um campo derived_from: [digest…] — a lista dos blobs exatos dos quais foi derivada. O conjunto forma um DAG de Merkle: células → manifestos → blobs; o digest raiz de um bake resume todo o corpus de entrada em 32 bytes.
Consequências imediatas:
- Re-auditoria retroativa. Qualquer defeito de transformação pode ser reproduzido contra os bytes originais, não contra o que o upstream sirva hoje.
- Detecção de revisões upstream. Um
etag/digest distinto na mesma URL distingue "a fonte revisou sua série" de "nosso pipeline mudou" — dois eventos que hoje são indistinguíveis. - Deduplicação de graça. O endereçamento por conteúdo colapsa respostas idênticas entre execuções; o custo de armazenamento cresce com a mudança real, não com a cadência de refresh.
A costura existente: scripts/freshness-guard.py já implementa snapshot→compare→repair para auditorias pontuais; a fase A o generaliza de ferramenta de auditoria para invariante do pipeline.
Fase B — Grafo de linhagem PROV-O consultável
/linaje narra a origem de cada série; a fase B o torna um grafo formal usando o vocabulário W3C PROV-O:
- Cada blob da fase A é uma
prov:Entity; cada execução de adaptador ou scriptbake-*é umaprov:Activity(prov:used→ insumos,prov:generated→ saídas); o pipeline e os operadores sãoprov:Agent. - Cada célula gerada no bake exporta sua cadeia como JSON-LD sob a API pública:
GET /api/v1/prov/{indicator}/{iso3}devolve o subgrafo mínimo que conecta o número em tela aos digests de seus blobs de origem. - O grafo é derivado, não mantido à mão: é emitido como subproduto da instrumentação dos ~50 scripts de bake, com um wrapper comum que registra
(insumos lidos, saídas escritas, digest de cada uma, versão do script).
O critério de sucesso é falseável: para qualquer número visível na plataforma, um cliente sem acesso ao repo pode percorrer o JSON-LD desde o citation_id até um digest de bytes crus, e verificar cada aresta com hashes.
Fase C — Bake reprodutível + atestações de build
A reprodutibilidade converte a linhagem em algo conferível, não só declarado:
- Bakes herméticos. Cada
bake-*.tsdeclara seus insumos por digest (fase A) e fica proibido de tocar a rede; as fontes de não-determinismo (timestamps, ordem de iteração de objetos, floats) são canonicalizadas —stableStringifyjá existe para os recibos do fundo fiduciário (server/trust/ledger.ts: serialização recursiva com chaves ordenadas, sobre a qualreceipt_hash = sha256(corpo canônico); o recibo é determinista dado o quádruplo contribuição +issued_at+ nonce + salt, e por isso reprodutível de forma independente) e é promovido a serializador de todo artefato gerado no bake. Meta:scores.jsonbit a bit idêntico dado o mesmo conjunto de insumos. - Atestações estilo in-toto/SLSA. Cada artefato de
public/data/**epublic/api/v1/**é acompanhado de uma atestação assinada:{ subject: digest_do_artefato, materials: [digests_de_insumos], builder: {repo, commit, script, versão}, invocation: {argv, env_permitido} }, assinada com Ed25519 por uma chave de build publicada. São publicadas sobpublic/api/v1/attestations/. - Verificação por terceiros. Com (1) + (2), um auditor externo — uma universidade, um banco multilateral, um governo que roda o mirror soberano — recomputa o bake sobre os mesmos blobs e compara digests. A confiança deixa de ser "acreditamos no Futuros" e passa a ser "nós recomputamos".
Nota de honestidade: a autenticação de emissor por HMAC do recibo do fundo fiduciário já está construída e é ativada por ambiente (TRUST_RECEIPT_HMAC_KEY): com a chave configurada, o recibo passa a esquema v2 e carrega uma assinatura HMAC-SHA256 sobre seu receipt_hash. Isso autentica o emissor mas não é verificável por terceiros, porque a verificação exige a chave secreta; a verificabilidade pública com Ed25519 segue no roadmap, e a chave de assinatura de build desta fase é seu pré-requisito.
Fase D — Log de transparência com ancoragem externa
Um ledger append-only operado pelo mesmo ator que escreve nele prova pouco: poderíamos reescrever a história e serví-la de novo. A fase D o torna economicamente impossível de falsificar:
- Árvore de Merkle estilo RFC 6962 (Certificate Transparency) sobre três séries: o registro de citações, o ledger do fundo fiduciário e as atestações de build. Cada entrada nova produz um checkpoint assinado
{tree_size, root_hash, timestamp}. - Provas de inclusão e consistência. Um recibo de contribuição ganha uma prova de inclusão de ~
log₂(n)hashes; quaisquer dois checkpoints admitem prova de consistência (nada foi apagado nem reescrito entre eles). Oreceipt_hashexistente é exatamente a folha de que a árvore precisa — zero migração de esquema. (E o recibo já selasalt_version— uma etiqueta pública one-way do salt que produziu ocontributor_id— de modo que uma rotação futura deTRUST_ID_SALTnão invalida a verificabilidade nem a revogabilidade de recibos antigos.) - Ancoragem externa periódica. O root é ancorado fora da nossa infraestrutura com cadência fixa: timestamping RFC 3161 e/ou OpenTimestamps (agregação no Bitcoin, custo ~zero), com o slot
chain_anchordo recibo — reservado desde o dia um — recebendo o identificador de ancoragem. Falsificar a história passada exigiria falsificar também a ancoragem externa datada. - Monitores. O checkpoint assinado é publicado na API pública; qualquer terceiro pode rodar um monitor que verifique consistência entre checkpoints — o mesmo modelo de auditoria distribuída do CT.
A forma do log, em esquema:
Fase E — Credenciais de conteúdo nos artefatos exportados
A procedência hoje viaja com o embed via citação sintética (Procedência); ela se perde no momento em que alguém exporta um PNG/SVG/CSV e o cola num relatório. A fase E anexa C2PA Content Credentials a cada export:
- O manifesto C2PA embutido declara: emissor (Futuros), os
citation_idde cada série plotada, digest do dataset de origem, timestamp assinado, e a asserção de que o render foi produzido a partir de dados citados sem edição manual. - Os CSV/XLSX de /datos-abiertos ganham um sidecar de atestação (
.csv+.csv.att.json) com o mesmo conteúdo — o formato tabular não admite manifesto embutido. - Resultado: um gráfico do Futuros que circula pelo WhatsApp ou por um deck ministerial continua verificável — qualquer verificador C2PA recupera as citações e o digest, e detecta edições.
Fase F — SLOs de frescor, deriva e ausência tipada
As fases A–E provam de onde veio um número; a fase F governa sua qualidade temporal — e codifica a lição mais cara das auditorias de dados deste projeto.
SLOs de frescor. refresh-meta.json já registra cadência e vencimento por fonte — hoje com last_refreshed / next_refresh_due em nível de feed (social:gdelt, doc:perplexity, …) e acompanhamento por indicador só para o subconjunto WB/WGI (49 códigos); o resto do corpus (884 séries no ledger de fontes) é rastreado em nível de feed, com o rollup de vintage em data-health.json. A fase F os converte em objetivos de nível de serviço com orçamento de staleness: cada fonte declara {cadência, carência, severidade}; o gate passa de binário (vencida/não) a um orçamento agregado que pode fazer o build falhar quando o corpus como um todo envelhece além do limiar, mesmo que nenhuma fonte individual esteja crítica.
Detecção estatística de deriva. Sobre os blobs da fase A: quando um refresh traz uma série revisada, um teste de deriva distribucional (PSI / Kolmogorov–Smirnov sobre a série sobreposta) classifica a mudança como revisão menor (re-bake silencioso com nota), revisão estrutural (exige entrada no changelog da fonte e re-verificação das células derivadas) ou anomalia de transporte (bloqueia o refresh — provavelmente é um erro nosso ou do upstream, não um dado novo). Complementa a detecção de anomalias ano a ano já publicada na camada de saúde do dado (|z| > 4 + piso de 10 pp, ver Metodologia).
Ausência tipada. O defeito recorrente mais perigoso encontrado nas auditorias internas do pipeline: um fetch que falhou escrito em disco como "não há dado". Uma célula vazia deve declarar por que está vazia, com um enum fechado:
absence: "no_data" # a fonte afirma que não existe medição
| "not_collected" # fora do escopo declarado da fonte
| "fetch_failed" # nosso transporte falhou — NÃO se sabe nada do valor
| "license_gated" # existe, mas a licença só permite citação
| "revoked" # existiu, o contribuinte revogou o consentimentoOs gates de build tratam fetch_failed como erro de refresh, jamais como dado: um valor prévio nunca é sobrescrito com uma ausência de transporte. A distinção license_gated/revoked conecta com a porta de licença e torna a revogação visível no corpus em vez de silenciosa.
Fase G — Prova ZK de registro
As fases C e D deixam o fundo fiduciário com duas peças: um compromisso determinista por registro e um log público que inclui esse compromisso. A fase G adiciona a terceira: provas de conhecimento zero que demonstram um predicado sobre o conteúdo de um registro sem revelar o registro.
A cadeia de dependência, elo por elo:
- Corpo canônico +
receipt_hash(em produção hoje; verificável por hash, sem assinatura).stableStringifyproduz uma serialização determinista do recibo ereceipt_hash = sha256(corpo canônico). É o único elo que já existe: um compromisso de 32 bytes por contribuição. - Prova de inclusão de Merkle (fase D, roadmap). Situa esse compromisso num log append-only com ancoragem externa. Sem D, uma prova ZK sobre um recibo não diz nada sobre o corpus: fala apenas de um blob que ninguém mais viu.
- Prova ZK de registro (esta fase). Um circuito toma o corpo canônico como testemunha privada, o
receipt_hashmais a raiz do log como entradas públicas, e prova afirmações do tipo "existe um registro incluído no checkpoint N cujoprivacyéaggregates_onlye que não foi revogado", sem expor contribuinte, dataset nem nenhum outro campo.
O desenho existente torna o circuito tratável: a folha da árvore é exatamente o receipt_hash, e o corpo canônico já é uma serialização estável com chaves ordenadas, ou seja, uma testemunha bem definida. A fase G não pede um redesenho do recibo; pede que D opere primeiro.
O que desbloqueia: divulgação seletiva (um auditor verifica uma propriedade de um registro sensível sem vê-lo), agregados demonstráveis (as contagens públicas por modo de privacidade passam de afirmação a prova) e o pré-requisito direto do roadmap ZK do pilar 2 (ver abaixo).
Estado honesto: não existe circuito, nem protótipo, nem escolha de esquema de prova. É a última fase da cadeia criptográfica e não começa antes de D estar em produção.
Fase H — Níveis de sensibilidade e criptografia por registro
O ponto de partida, verificável em server/trust/ledger.ts:
PrivacyModeé metadado declarado, não um controle técnico. O contribuinte escolheopen | aggregates_only | clean_room | private_compute; o modo governa a pontuação e como a contribuição é agregada, mas hoje não ativa criptografia nem controle de acesso criptográfico algum.- O armazenamento é em claro. O ledger persiste os registros sem criptografia no backend do operador.
- A pseudonímia vem de
TRUST_ID_SALT. Ocontributor_idé um hash com salt do email, comsalt_versionselado no recibo para que a rotação de salt não quebre a revogação. É pseudonímia, não criptografia: protege a identidade diante de leitores do ledger, não o conteúdo diante do operador.
A fase H fecha a distância entre o declarado e o aplicado com dois movimentos:
- Níveis de sensibilidade por registro. Cada registro é classificado num nível fechado:
T0público,T1pseudonimizado (o estado atual),T2sensível, criptografado em repouso,T3nunca sai do contribuinte (o "computar sem possuir" queprivate_computejá declara). O nível padrão deriva doPrivacyModedeclarado, que deixa de ser só uma etiqueta. - Criptografia por registro com chaves por contribuinte. Os níveis
T2eT3usam envelope encryption: uma chave de dados por registro, envolvida por uma chave por contribuinte. A revogação ganha um mecanismo criptográfico: destruir a chave (crypto-shredding) torna o registro ilegível sem reescrever o log, compatível com a árvore append-only da fase D, onde oreceipt_hashpermanece como evidência de que o registro existiu.
Dependências: a criptografia em repouso não exige nem G nem D, mas a evidência verificável de uma revogação (provar que a capacidade de descriptografar foi destruída) se apoia sim no log da fase D. E H é o pré-requisito de dados da inferência ZK do pilar 2: sem registros criptografados não há "inferência sobre registros criptografados".
Um único fio com o pilar 2: inferência ZK sobre registros criptografados
O roadmap do pilar 2, Modelo Soberano inclui inferência com conhecimento zero sobre registros criptografados do fundo fiduciário. Esse item e as fases G e H desta página são uma única cadeia de dependência, não promessas paralelas:
receipt_hash sobre corpo canônico (em produção) → prova de inclusão de Merkle (fase D) → prova ZK de registro (fase G) + registros criptografados por nível (fase H) → inferência ZK sobre registros criptografados (pilar 2).
Nenhum elo depois do primeiro existe hoje. Se alguma página desta documentação chegasse a apresentar a inferência ZK do pilar 2 como capacidade sem que G e H operem aqui, isso seria um defeito reportável no mesmo espírito do log de falsificações.
Sequência e dependências
| Fase | Depende de | Custo dominante | O que desbloqueia |
|---|---|---|---|
| A — CAS de aquisição | — | Armazenamento de blobs (cresce com a mudança, não com a cadência) | Re-auditoria, detecção de revisões, o DAG |
| B — Linhagem PROV-O | A | Instrumentar os ~50 scripts de bake com um wrapper comum | Procedência consultável por máquina, por célula |
| C — Bakes reprodutíveis + atestações | A | Canonicalizar o não-determinismo; gestão da chave de build | Verificação por terceiros; a assinatura do recibo |
| D — Log de transparência + ancoragem | C (chave) | Operar o log + monitores | História não-reescrevível; chain_anchor deixa de ser null |
| E — Credenciais C2PA | C | Tooling de manifestos no pipeline de export | Procedência que sobrevive fora da plataforma |
| F — SLOs + deriva + ausência tipada | A (para deriva) | Migração do esquema de células para o enum de ausência | Frescor governado; fim da classe de defeito "fetch falhou = não há dado" |
| G — Prova ZK de registro | D | Desenho do circuito e escolha do esquema de prova | Divulgação seletiva; agregados demonstráveis; o pré-requisito ZK do pilar 2 |
| H — Sensibilidade + criptografia por registro | D (para evidência de revogação) | Gestão de chaves por contribuinte; migração do armazenamento | Criptografia em repouso por nível; revogação por destruição de chave |
O que cada fase torna verificável — e quem pode conferi-lo sem confiar no Futuros:
| Fase | O que se torna verificável | Verificador | Artefato que o prova |
|---|---|---|---|
| A | Que os bytes upstream são exatamente os ingeridos | Auditor com acesso aos blobs | Digest SHA-256 + manifesto de fetch |
| B | A cadeia completa célula → blob de origem | Qualquer cliente HTTP, sem acesso ao repo | JSON-LD sob /api/v1/prov/… |
| C | Que o bake é recomputado bit a bit | Terceiro que roda o mirror soberano | Atestação assinada Ed25519 |
| D | Que a história não foi reescrita | Monitor externo contínuo, estilo CT | Provas de inclusão/consistência + ancoragem datada |
| E | A procedência de um export fora da plataforma | Qualquer verificador C2PA padrão | Manifesto embutido ou sidecar .att.json |
| F | Por que uma célula está vazia e quanto o corpus envelheceu | Os gates de build + o leitor | Enum de ausência + orçamento de staleness |
| G | Um predicado sobre um registro, sem revelar o registro | Qualquer verificador com o checkpoint do log | Prova ZK + prova de inclusão |
| H | Que uma revogação destruiu a capacidade de descriptografar | Auditor com o log e o registro de chaves | Evento de destruição de chave ancorado no log |
A e F-ausência-tipada são os pontos de partida corretos: A é o pré-requisito de tudo o que é criptográfico, e a ausência tipada elimina hoje a classe de defeito que mais vezes produziu dados falsos-por-omissão. D e E são os de maior visibilidade externa, mas só fazem sentido sobre C. G e H fecham a cadeia: G só existe sobre D, e a inferência ZK do pilar 2 só sobre G e H.
A regra que governa todo o roadmap é a mesma do resto da plataforma: nenhuma fase é anunciada como capacidade até que sua verificação seja executável por um terceiro. Enquanto isso, esta página é o compromisso público de para onde se otimiza — no mesmo espírito falseável do log de falsificações.