PaceProof
Verifica registros de atestação assinados com Ed25519 e gera relatórios de auditoria por meio de ferramentas MCP.
Documentação
PaceProof
O PaceProof verifica registros de atestação de computação assinados com Ed25519 de qualquer provedor e informa exatamente quais são reais.

Um registro com assinatura ausente, malformada ou adulterada nunca é incorporado a um total "verificado"; ele é contado e relatado separadamente, sempre, tanto na saída legível para humanos quanto na saída --json.
O PaceProof não assina nem gera atestações. Ele é uma camada neutra, somente leitura, de ingestão/verificação/relatório/dashboard sobre registros que já foram assinados em outro lugar. Aponte-o para um diretório, arquivo ou URL de registros assinados e ele informa, de forma verificável, qual computação foi realmente executada, por quem, e se a assinatura de cada registro é válida.
Instalação
O paceproof-cli é publicado tanto no npm quanto no PyPI:
npm install -g paceproof-cli
# or
pip install paceproof-cli
Ambos os comandos instalam um binário paceproof. O paceproof-cli também está disponível como alias em ambos os registros, caso você precise diferenciá-lo de outra ferramenta no seu PATH.
Para compilar a partir do código-fonte (útil se você estiver contribuindo ou quiser o estado exato do repositório em vez de uma versão publicada):
TypeScript (pacote npm, inclui o servidor MCP):
git clone https://github.com/RudrenduPaul/PaceProof.git
cd PaceProof/packages/cli-ts
npm install
npm run build
node dist/bin.js --help
Python (pacote PyPI, reimplementação independente):
git clone https://github.com/RudrenduPaul/PaceProof.git
cd PaceProof/packages/cli-py
pip install -e .
paceproof --help
Tanto os comandos publicados npm install -g paceproof-cli quanto pip install paceproof-cli acima foram executados do zero em um ambiente limpo durante a escrita deste README, e a saída do quickstart abaixo é a saída real dessas instalações, não fabricada.
Sumário
- Recursos
- Quickstart
- Referência de comandos da CLI
- Referência da API da biblioteca
- Como a verificação funciona
- Comparação
- O que é o PaceProof e por que ele existe
- FAQ
- Contribuindo
- Licença
Quickstart
paceproof init
paceproof report ./paceproof-example
O paceproof init gera um novo par de chaves Ed25519 de exemplo e 7 registros de atestação de exemplo: 3 assinados validamente e 4 intencionalmente quebrados (um payload adulterado, uma assinatura com chave errada, uma assinatura malformada e uma assinatura ausente) para que o verify/report tenham modos de falha reais para demonstrar, não apenas um caminho feliz.
Saída real de uma execução real contra o pacote npm publicado:
$ paceproof report ./paceproof-example
PaceProof report -- source: ./paceproof-example
generated at: 2026-08-04T02:54:30.898Z
== VERIFIED ==
records: 3
compute total: 144.50 gpu_hours
== UNVERIFIED (never counted in verified totals above) ==
records: 4
compute total: 1009 gpu_hours
reasons:
- rec-004: signature does not match record contents
- rec-005: signature does not match record contents
- rec-006: signature must decode to 64 bytes, got 4
- rec-007: schema validation failed: (root) must have required property 'signature'
== BY PROVIDER ==
acme-cloud: verified=132 gpu_hours (2 records); unverified_count=0
beta-compute: verified=12.50 gpu_hours (1 records); unverified_count=0
gamma-hpc: verified=(none); unverified_count=2
delta-cloud: verified=(none); unverified_count=2
== BY WORKLOAD TYPE ==
training: verified=128 gpu_hours (1 records); unverified_count=1
inference: verified=12.50 gpu_hours (1 records); unverified_count=1
idle: verified=4 gpu_hours (1 records); unverified_count=1
unknown: verified=(none); unverified_count=1
O verify sai com código não zero quando qualquer registro falha (código de saída real de uma execução real: 1, com 4 registros não verificados presentes):
$ paceproof verify ./paceproof-example
Verified: 3
Unverified: 4
FAIL rec-004: signature does not match record contents
FAIL rec-005: signature does not match record contents
FAIL rec-006: signature must decode to 64 bytes, got 4
FAIL rec-007: schema validation failed: (root) must have required property 'signature'
$ echo $?
1

Renderize um dashboard a partir dos mesmos dados:
paceproof dashboard ./paceproof-example --out dashboard.html

Tanto a compilação TypeScript quanto a Python foram executadas contra o paceproof-example para este README, e ambas produziram as mesmas contagens verificadas/não verificadas e totais mostrados acima.
Recursos
- Adaptadores de fonte de dados plugáveis. O
ingestnormaliza entrada arbitrária para o esquema canônico por meio de uma interfaceAdapterdocumentada (interface TypeScript, ABC Python). O adaptadorjsonlincluído lê JSON delimitado por nova linha já na forma canônica; um adaptador específico de provedor (por exemplo, para a exportação nativa do ComputeLedger) implementa a mesma interface sem tocar no agregador, no renderizador de relatórios ou na fiação da CLI. - Verificação Ed25519 com separação estrita verificado/não verificado. Cada registro é verificado quanto à validade do esquema e à validade da assinatura. Um registro que falha em qualquer uma das verificações nunca é mesclado silenciosamente em um total verificado: contagens verificadas e não verificadas e totais de computação são calculados a partir de conjuntos disjuntos e mostrados lado a lado em todos os relatórios.
- Duas implementações independentes e testadas por paridade. O pacote TypeScript (npm) e o pacote Python (PyPI) são implementações reais e separadas, não um wrapper de uma sobre a outra. Ambos produzem saída
report --jsonbyte idêntica para a mesma entrada; um job de CI executa a saída da CLI TypeScript contra a saída da CLI Python em um fixture compartilhado em ambas as direções e falha a compilação em qualquer divergência. - Dashboard HTML estático autocontido. O
paceproof dashboardrenderiza um único arquivo HTML com CSS inline e sem JavaScript: sem fontes de CDN, sem scripts externos, sem requisições remotas de qualquer tipo. Atualmente inclui um tema claro limpo; ainda não há alternância de modo escuro. - Servidor MCP para invocação por agentes. O
paceproof mcpinicia um servidor Model Context Protocol expondoverify,ingestereportcomo ferramentas chamáveis, para que um agente orquestrador possa chamar o PaceProof programaticamente em vez de invocar uma CLI voltada a humanos. Os handlers das ferramentas são wrappers finos em torno das mesmas funções de agregação/relatório que a própria CLI chama, sem reimplementação separada para o caminho MCP. - Endurecido por segurança por design, não por reflexão tardia. Os buckets de agregação são construídos com
Object.create(null)para que um campoprovideroucompute_unitcontrolado por atacante, como"__proto__", não possa poluir oObject.prototype. A única chamada de rede que o PaceProof faz (ingest <url>) é limitada por um timeout de 30 segundos e um teto de resposta de 50 MiB, aplicado contra a contagem real de bytes transmitidos, em vez de confiar em um cabeçalhoContent-Length. Cada campo do esquema carrega um comprimento máximo explícito para que entrada superdimensionada não possa esgotar a memória antes da validação.
Referência de comandos da CLI
Cada tabela abaixo é copiada da saída real do --help do pacote npm paceproof-cli publicado (v0.1.0).
paceproof init [path]
Cria um diretório de exemplo com um par de chaves de amostra e registros de exemplo assinados validamente/invalidamente.
| Argumento | Descrição |
|---|---|
path | Diretório a criar (padrão: ./paceproof-example) |
paceproof verify <path>
Verifica assinaturas Ed25519 em cada registro encontrado em <path>.
| Opção | Descrição |
|---|---|
--json | Gera JSON estruturado em vez de uma tabela legível para humanos |
--adapter <name> | Adaptador a usar para ler a entrada (padrão: jsonl) |
paceproof ingest <path-or-url>
Executa um adaptador nomeado sobre a entrada e emite registros normalizados no esquema canônico como JSONL.
| Opção | Descrição |
|---|---|
--adapter <name> | Adaptador a usar (padrão: jsonl) |
--out <file> | Grava a saída JSONL em um arquivo em vez de stdout |
paceproof report <path>
Ingere e verifica registros em <path> e então agrega em um relatório resumido.
| Opção | Descrição |
|---|---|
--json | Gera JSON estruturado em vez de uma tabela legível para humanos |
--adapter <name> | Adaptador a usar para ler a entrada (padrão: jsonl) |
paceproof dashboard <path>
Renderiza um único dashboard HTML estático autocontido a partir de um relatório.
| Opção | Descrição |
|---|---|
--out <file> | Caminho do arquivo HTML de saída (padrão: paceproof-dashboard.html) |
--adapter <name> | Adaptador a usar para ler a entrada (padrão: jsonl) |
paceproof mcp
Inicia um servidor MCP expondo verify, ingest e report como ferramentas chamáveis. Somente pacote TypeScript por enquanto: executar paceproof mcp a partir do pacote Python imprime uma mensagem apontando para o pacote npm e sai com código não zero.
Todo comando suporta códigos de saída não zero reais em caso de falha ou falha de verificação, e --help em todo subcomando.
Referência da API da biblioteca
O pacote npm também exporta seus internos diretamente (main/types em package.json apontam para código de biblioteca real, não apenas o ponto de entrada da CLI), para quem estiver construindo um adaptador personalizado ou incorporando lógica de verificação em outra ferramenta em vez de invocar a CLI. Essa superfície é somente TypeScript; o pacote Python expõe paceproof como CLI apenas, sem API de importação documentada.
import { getAdapter, verifyRecords, summarize } from 'paceproof-cli';
import type { Adapter } from 'paceproof-cli';
const records = await getAdapter('jsonl').read('./paceproof-example/records.jsonl');
const outcomes = verifyRecords(records);
const report = summarize(outcomes);
| Export | Assinatura | O que faz |
|---|---|---|
Adapter | interface Adapter { readonly name: string; read(input: string): Promise<RawRecord[]> } | O ponto de extensibilidade descrito acima. Implemente-o para normalizar o formato de exportação de um novo provedor em registros canônicos. |
getAdapter(name) | (name: string) => Adapter | Busca um adaptador registrado pelo nome (jsonl já vem embutido); lança erro se o nome não estiver registrado. |
verifyRecord(raw) | (raw: RawRecord) => VerificationOutcome | Valida o esquema e verifica a assinatura de um único registro. |
verifyRecords(raws) | (raws: RawRecord[]) => VerificationOutcome[] | Executa verifyRecord sobre um lote. |
summarize(outcomes) | (outcomes: VerificationOutcome[]) => ReportSummary | Agrega resultados de verificação na mesma estrutura verificado/não verificado por provedor/por tipo de carga de trabalho que o paceproof report --json imprime. |
verifyRecordSignature(record) | (record: AttestationRecord) => SignatureCheckResult | Verifica apenas a assinatura Ed25519 (a validação de esquema é separada), contra a codificação JSON canônica descrita abaixo. |
canonicalizeRecord(record) | (record: Record<string, unknown>) => Uint8Array | Produz a codificação canônica de bytes sobre a qual uma assinatura é calculada e verificada: chaves ordenadas lexicograficamente, UTF-8, sem espaços em branco insignificantes. |
buildCli() | () => Command | Retorna a instância Command do Commander.js que a própria CLI publicada executa, se você quiser incorporá-la ou estendê-la em vez de reimplementar o parsing de argumentos. |
Não há um site de documentação de API gerado separadamente (ainda não há build TypeDoc no CI) — a tabela acima é a referência até que um exista. Cada assinatura foi extraída diretamente do packages/cli-ts/src/ em 03/08/2026, não reconstruída de memória.
Como a verificação funciona
Cada registro de atestação é um objeto JSON validado contra um único JSON Schema canônico (schema/attestation-record.schema.json), o mesmo arquivo, byte por byte, que tanto o pacote TypeScript quanto o Python enviam e contra o qual validam. Um registro precisa de record_id, issued_at, provider, hardware, workload_type, compute_amount, compute_unit, issuer_public_key e signature; todo campo de string tem um comprimento máximo explícito para que entrada malformada ou superdimensionada falhe rapidamente em vez de ser analisada primeiro e limitada depois.
O campo signature é uma assinatura Ed25519 sobre a codificação JSON canônica de todos os outros campos: chaves de objeto ordenadas lexicograficamente, codificação UTF-8, sem espaços em branco insignificantes, números renderizados sem um + inicial ou zeros finais desnecessários. Ambas as implementações produzem JSON canônico byte idêntico para o mesmo registro, então uma assinatura verificada por uma implementação é verificada pela outra.
Um registro é "verificado" somente se passar em ambas as verificações: válido no esquema e válido na assinatura. Qualquer outra coisa (uma assinatura ausente, uma assinatura que decodifica para o comprimento de bytes errado, uma assinatura que não corresponde ao payload, uma assinatura feita com a chave errada) é "não verificado". Esses dois conjuntos são sempre disjuntos no código do agregador, não apenas na forma como um relatório os renderiza: totais de computação verificados e não verificados são acumulados em estruturas separadas, e não há caminho de código que adicione o compute_amount de um registro não verificado a um total verificado. Uma ferramenta de relatório que silenciosamente confunde números "declarados" e "comprovados" lava reivindicações não verificáveis em algo que parece verificado, o que anula o propósito de uma trilha de auditoria.
Comparação
Contagens de estrelas e descrições abaixo foram verificadas ao vivo contra a listagem da API do GitHub e o README de cada projeto em 03/08/2026; nada é inventado ou reutilizado de memória.
| Projeto | Estrelas | O que faz | Como difere do PaceProof |
|---|---|---|---|
| meghabyte/verifiable-training | 10 | Código de pesquisa da Stanford NeurIPS 2024 ("Optimistic Verifiable Training by Controlling Hardware Nondeterminism") que elimina o não determinismo de hardware para que execuções de treinamento reproduzam pesos byte-idênticos em diferentes GPUs, e então constrói árvores de Merkle sobre checkpoints para um verificador auditar. | Prova que aquele treinamento específico aconteceu como afirmado no nível de pesos, como um protótipo de pesquisa de geração de atestados, não uma ferramenta de ingestão/verificação/relatório. Sem adaptadores, sem ingestão entre provedores de registros assinados pré-existentes, sem CLI, sem paridade entre linguagens, sem superfície MCP. |
| skypilot-org/skypilot | 10.441 | Orquestração de computação de IA multi-nuvem e agendamento ciente de custos em mais de 20 nuvens, Kubernetes e Slurm. | Visibilidade e agendamento de custo e utilização, não verificação criptográfica. Ele nunca verifica uma assinatura nem separa um número "verificado" de um "reivindicado"; não há formato de registro de atestado envolvido. |
| opencost/opencost | 6.659 | Monitoramento de custos de Kubernetes e nuvem e visibilidade de alocação (Apache 2.0, originalmente Kubecost). | Mesma categoria do SkyPilot: visibilidade de uso e custo sobre dados de faturamento e métricas, não atestação criptográfica. Sem verificação Ed25519, sem divisão verificado/não verificado, sem esquema de registro de atestado. |
| RudrenduPaul/ComputeLedger | 0 | CLI, biblioteca e servidor MCP agnósticos de provedor para assinatura, encadeamento de hash e verificação independente de recibos de uso de computação (horas de GPU, hardware, tipo de carga de trabalho) com assinaturas Ed25519 e um livro-razão local à prova de adulteração. | Complementar, não concorrente: projeto irmão do mesmo autor, e a metade de geração de atestados deste problema. O PaceProof é a metade de ingestão/verificação/relatório. Aponte-o para registros do ComputeLedger, ou de qualquer outra fonte de assinatura Ed25519, e ele relata o que verifica. |
Buscas mais amplas por uma ferramenta diretamente comparável que "ingira registros de atestado de computação assinados de vários provedores, verifique assinaturas Ed25519, mantenha totais verificados e não verificados separados" não encontraram nada além dessa combinação específica em 2026-08-03. A categoria adjacente mais próxima é a verificação genérica de atestação remota de hardware (por exemplo, veraison/services, 47 estrelas, evidência TPM/SEV-SNP/SGX/TDX): um domínio de atestação diferente (estado de inicialização/execução de hardware, não registros de uso de computação) sem esquema de atestado de computação, sem modelo de adaptador e sem relatórios de horas de computação.
O que é o PaceProof e por que ele existe
As alegações de uso de computação de laboratórios de IA, provedores de nuvem e operadores de infraestrutura estão se tornando mais difíceis de verificar de forma independente à medida que o volume de discurso relacionado à computação cresce. A carta aberta real "Pacing the Frontier", assinada em julho de 2026 por mais de mil funcionários da OpenAI, Anthropic, Google DeepMind e Meta pedindo ferramentas verificáveis para ritmar o desenvolvimento de IA de fronteira, é um exemplo dessa conversa da indústria, citada aqui apenas como contexto motivador. O PaceProof não é afiliado a ela, não foi construído em resposta a qualquer pedido de seus signatários e não faz nenhuma alegação de endosso ou parceria.
Para ser direto sobre a única coisa que este README precisa deixar inequívoca: não existe um tratado real de "Verified Slowdown", e nenhum tratado desse tipo existe hoje. Essa frase vem de um cenário especulativo de previsão em ai-2027.com, não de qualquer acordo internacional, lei ou órgão regulador real. O PaceProof não implementa, aplica ou certifica conformidade com qualquer tratado, lei ou regulamento, porque não existe tal tratado, lei ou regulamento aplicável a esta ferramenta.
O que o PaceProof realmente é: uma camada de relatórios neutra e criptograficamente verificável sobre dados de atestado de computação que você já possui. Se você (ou um provedor com quem você trabalha) já produz registros de atestado assinados, seja por meio do ComputeLedger, de um pipeline de assinatura personalizado ou de qualquer outra coisa que emita registros assinados com Ed25519, o PaceProof informa quais desses registros realmente se sustentam criptograficamente e totaliza apenas os que se sustentam, separados claramente dos que não se sustentam. Isso é útil hoje para trilhas de auditoria internas e transparência de uso entre provedores. Não é, e não afirma ser, software de conformidade para um regulamento que não existe.
Perguntas Frequentes
O que é o PaceProof e o que o torna diferente de uma ferramenta genérica de monitoramento de custos? O PaceProof é um CLI e servidor MCP somente leitura que verifica assinaturas Ed25519 em registros de atestado de computação e relata totais com números verificados e não verificados estritamente separados, nunca mesclados. Ferramentas de visibilidade de custo como SkyPilot ou OpenCost relatam o que um sistema de faturamento diz que foi usado; o PaceProof relata o que uma assinatura criptográfica realmente prova, e sinaliza todo o resto como não verificado em vez de contá-lo silenciosamente.
O PaceProof fornece conformidade legal ou regulatória? Não. Não existe um tratado real de "Verified Slowdown" ou regulamentação comparável para o PaceProof cumprir, e o PaceProof não faz nenhuma alegação de conformidade de qualquer tipo. Ele verifica assinaturas Ed25519 em registros que você fornece e relata os resultados. Trate sua saída como um relatório de verificação criptográfica, não uma certificação legal ou regulatória.
O PaceProof assina ou gera registros de atestado? Não. O PaceProof é somente leitura: ele ingere, verifica e relata sobre registros que já estão assinados em outro lugar. Se você precisar gerar registros de atestado de computação assinados, isso é uma preocupação separada; veja ComputeLedger, um projeto irmão do mesmo autor, para o lado da assinatura.
Como o PaceProof é diferente do ComputeLedger? Eles são complementares, não concorrentes, e construídos pelo mesmo autor. O ComputeLedger assina e encadeia hashes de recibos de uso de computação; o PaceProof ingere e verifica registros que já estão assinados, do ComputeLedger ou de qualquer outra fonte de assinatura Ed25519. Se você precisa produzir registros assinados, use o ComputeLedger. Se você precisa verificar independentemente registros que já possui, use o PaceProof.
O que acontece com um registro com assinatura inválida? Ele é simplesmente descartado?
Não. Um registro que falha na validação de esquema ou na verificação de assinatura nunca é descartado ou excluído silenciosamente. Ele é contado em unverified_count, seu valor de computação é totalizado separadamente em unverified_compute_total_by_unit, e o motivo específico da falha (payload adulterado, chave errada, assinatura malformada, campo ausente) é relatado junto. Nada sobre um registro com falha desaparece da saída.
Posso adicionar suporte para um provedor cujo formato de exportação não seja JSONL?
Sim, é para isso que serve a interface de adaptador. Implemente a interface Adapter (TypeScript) ou o ABC Adapter (Python): um método name e um read(input) que retorna registros já normalizados para o esquema canônico. Você não precisa mexer no agregador, no renderizador de relatórios ou na fiação CLI existente além de registrar o nome do novo adaptador.
O paceproof ingest <url> faz chamadas de rede arbitrárias?
Apenas a que você explicitamente pedir. Todos os outros comandos operam em arquivos locais. ingest <url> é a única chamada de rede opcional em toda a ferramenta, e é limitada: um timeout de 30 segundos e um limite de resposta de 50 MiB aplicado contra a contagem real de bytes transmitidos, não apenas um cabeçalho Content-Length que o servidor remoto poderia mentir.
O PaceProof funciona no Windows, macOS e Linux? O pacote npm requer Node.js 18 ou mais recente e não tem código específico de SO, então roda em qualquer lugar onde o Node roda, incluindo Windows, macOS e Linux. O pacote Python requer Python 3.10 ou mais recente e está listado como Independente de SO no PyPI. Ambos são ferramentas puras de userland sem dependências nativas compiladas.
Por que há duas implementações em vez de um único CLI com bindings?
Para que cada pacote seja uma coisa real e independente que você possa instalar do seu registro nativo (npm ou PyPI) sem puxar um runtime para a outra linguagem. Um arquivo JSON Schema compartilhado e uma suíte de testes de paridade entre linguagens (executada em ambas as direções no CI) mantêm a saída report --json idêntica, então qual implementação você escolher não muda o que você obtém.
O servidor MCP está disponível no pacote Python?
Atualmente não. paceproof mcp é somente TypeScript por enquanto: executá-lo a partir do pacote Python imprime uma mensagem apontando para o pacote npm e sai com código não zero. Todos os outros comandos (init, verify, ingest, report, dashboard) são uma implementação Python completa e independente.
Sob qual licença está o PaceProof e posso usá-lo comercialmente? MIT. Você pode usar, modificar e redistribuir o PaceProof comercialmente sem royalties e sem a obrigação de abrir o código-fonte do seu próprio código, sujeito apenas a manter o aviso de direitos autorais e o texto da licença conforme os termos da licença MIT.
Contribuindo
CI (.github/workflows/ci.yml) executa três jobs em cada push e PR para main: lint + typecheck + teste TypeScript, lint Python (ruff) + typecheck (mypy --strict) + teste (pytest) em Python 3.10 e 3.13, e um job de paridade entre linguagens que compila o CLI TypeScript, instala o CLI Python e executa o teste de paridade de cada lado contra o CLI do outro como subprocesso.
Para executar tudo localmente:
# TypeScript
cd packages/cli-ts
npm install
npm run lint
npm run typecheck
npm test # 60 tests, Vitest
# Python
cd packages/cli-py
pip install -e ".[dev]"
ruff check src tests
mypy src
pytest -q # 52 tests
Se você alterar o esquema, atualize schema/attestation-record.schema.json na raiz do repositório e suas cópias em packages/cli-ts/schema/ e packages/cli-py/src/paceproof_cli/schema/, e atualize a lógica de validação de ambas as implementações. Um teste de paridade na suíte de cada pacote verifica sua cópia local do esquema contra o arquivo raiz e falha no CI se eles divergirem.
Veja ARCHITECTURE.md para o layout completo do repositório, as regras JSON canônicas sobre as quais a assinatura é calculada e como a interface de adaptador e o servidor MCP se encaixam.
Licença
MIT. Veja LICENSE.