How it works
NEAR TESTNET · PROOFSTREAM-V1.TESTNET
ProofStream pays contributors in USDC that sits in escrow against one milestone of a GitHub repository, and stays locked until the work is checked twice: the hard facts of the merged pull request, read inside an Intel TDX enclave, and the work itself, judged by two AIs from different vendors. The contract pays the lower of the two shares. No human approves a payment, and no AI can release one alone.
The shape of it
- Fundthe funder escrows the budget in full
- Bindthe contributor names where to be paid, with a gist
- Claima merged PR's hard facts, checked in TDX
- Reviewthe judge, then a signed second opinion
- Paythe lower share, straight to the bound account
- A funder creates a milestone and deposits the budget plus the review fee in one transfer. The contract pins the repository by its numeric GitHub id, the contributor by theirs, the branch, the required CI checks, a deadline, and the exact wasm hash of every enclave program. Nothing is claimable until the deposit lands in full.
- The contributor binds a payout account by posting a public gist that names the contract, the milestone, a one-time nonce and a NEAR account. The binder reads it inside TDX and confirms its owner holds the milestone's GitHub id; the contract then checks the account exists (or creates a 64-character implicit account) and registers it with the token. From then on, money can only go there.
- A pull request merges, and someone claims it. The checker reads GitHub's API inside TDX: merged into the right repository and branch, by the right author, after the milestone was created, with every required check successful, nothing under
.github/changed, the complete file list returned, and a human other than the author merging it or approving that exact commit. The contract applies the rules and locks the pull request against every other milestone. - The judge reviews. It fetches the diff and the milestone text, asks GLM on NEAR AI Cloud how much of the milestone is done, earlier paid work included, and checks the model's signature inside the enclave. If it objects, it stops: no second opinion is bought.
- The judge buys a second opinion. It pays the verifier $0.02 over OutLayer's API from its owner's payment key. The verifier is a separate project with its own owner and a different model, Qwen; it reads the same contract-built input, never the judge's answer, and signs its verdict with a key that exists only inside its enclave.
- The contract decides. It checks the verifier's signature on-chain, over a message it builds itself, against the key pinned in the milestone. Any objection holds the money for the funder. Two shares more than 30 points apart hold it too. Otherwise the lower share is certified, and only the newly certified part of the budget is paid.
- The milestone stays open. A later pull request earns only what it adds. After the deadline, the funder takes back whatever was never certified.
The system
What the bar means
Every milestone page carries a bar of 50 cells, each 2% of the budget. Green means one thing everywhere in this interface: USDC the contract has paid out.
The states
How the two AIs decide
The rules
- Each AI answers meets (100%), partial (1–99%), does not meet or unclear. A verdict that disagrees with its own percent is no verdict.
- Any objection holds the money for the funder. So do two shares more than 30 points apart, and a share that adds nothing new.
- Otherwise the lower share is certified. Certified only rises, and each payment is the newly certified part.
- Both see the earlier paid pull requests, marked as paid, so redoing paid work earns nothing.
- No verdict (a timeout, a bad signature) counts an attempt and lets anyone ask again, up to the funder's limit.
The signed second opinion
The verifier signs proofstream-verdict:v1:{contract}:{milestone}:{attempt}:{commit}:{verdict}:{percent}:{caller} with an ed25519 key that OutLayer derives inside its enclave and never exports. The contract rebuilds that message from its own state and checks the signature with ed25519_verify, against the key pinned in the milestone, and checks that the judge's owner paid for the run. A verdict the judge changed, a signature from another attempt, milestone or commit, or one by another key, is no verdict at all.
What the contract guarantees
- Nothing is claimable until the deposit lands in full. A transfer of any other amount comes straight back.
- Money only goes to the bound account. Neither the funder, the relayer nor the operators can redirect a payout.
- A pull request is paid once, across every milestone. It is locked while it is being checked, and spent once paid.
- The code that judges is fixed per milestone. Every enclave program is pinned by wasm hash at creation, and the milestone keeps those pins forever.
- The contract has no admin. No owner, no setter, no upgrade method. Its code hash matches the reproducible build in CI.
- The books reconcile. What the contract holds equals what it owes, at all times;
reconcile()shows it.
What is attested, checked and trusted
- Attested
- Each run's TDX quote binds the project id, the wasm hash that ran, and the input and output. The AI's role comes from the OutLayer project the contract called. The worker sets it, and neither the input nor the secrets can change it. The project id, the wasm hash, the input and the output (which echoes the role) are all bound into the execution's TDX quote. The contract refuses a verdict from the wrong role; the quote itself is checked off-chain, by anyone, with
scripts/verify-execution.py, not by the contract. - Checked on-chain
- Every rule and payout; the verifier's signature; that results come from a worker whose key was added only after its TDX quote passed.
- Checked by anyone
- Each execution's quote, down to Intel's signature:
python3 -I scripts/verify-execution.py <tx>. - Trusted
- GitHub's API for the facts; OutLayer's measurement allowlist and keystore; NEAR AI's TEE and its signing key; the people who merge. The verifier's key belongs to its project, so a new version published by its owner would sign with the same key.
Check it yourself
git clone https://github.com/Samuel-Chuku/proofstream-near && cd proofstream-near cd contract && cargo test --lib # every contract rule, including each refusal cargo test --test sandbox # a local NEAR node, a real token, the books reconciling cd ../outlayer/ai-review && cargo test # unsigned, altered or off-commit answers refused python3 -I scripts/verify-execution.py <tx hash> # one run's TDX quote, down to Intel
Limitations, named
- The judge and verifier are run by the same people for now. They are independent in keys, accounts and models, not in operator.
- A contributor can weaken their own tests. The AIs are told to look for it, and can miss it.
- A second GitHub account defeats the independent-approval rule.
- Partial shares are a model's estimate, bounded by two models, the lower one and the 30-point gap.
- A funder who disagrees can reject, and refund after the deadline. The contributor's protection is the milestone text and deadline they read before starting, and the public record of every rejection and its reason.
- Public repositories only, and testnet only: the USDC is free to mint.
Addresses
- Contract
- proofstream-v1.testnet ↗
- Token
- usdc.fakes.testnet ↗
- Relayer
- relayer.proofstream.site ↗ · proofstream-relayer.testnet
- Judge
- proofstream-checker-owner.testnet/proofstream-judge
- Verifier
- proofstream-verifier-owner.testnet/proofstream-verifier · key 6abd46ea8cb3bffd74a8b4acce3d9a1fef81956e57ef86dd3f0970a00e25c7f1
- Builds
- builds.json, from the reproducible CI build
Getting started
You need a NEAR testnet wallet with a little NEAR, and test USDC, which the app mints for you in one click. Contributors need neither.