Search projects, hackathons, sponsors and tech

    ← All projects

    Petri

    Darwinian evolution for AI agents: harnesses mutate, get tested, and only verified winners survive.

    Demo

    About

    Petri is a version tree for AI agent harnesses. A harness is the code around a model: the prompt, the retry loop, and the context it reads. Petri records every change to a harness, measures it, and lets other people check the result. Continuity Track: Petri was a finalist at ETHGlobal Online 2026. At ETHGlobal Tokyo we build on the same idea, and we add 3 partner tracks: ENSv2, World ID and Intercepta. The problem: - Nobody measures. Teams change a prompt and say the agent "feels better". - Failures stay private. A dead end stays in one terminal, so the next engineer tries the same idea again. - Nobody can check a claim. The harness and the benchmark are not published. How Petri works: - Each version holds a hypothesis in plain English, a benchmark score, and signatures from the keys that re-ran it. - The score is the median of 5 runs on 20 coding tasks. - A version is accepted only when 2 other keys re-run it and each measures a gain of at least 10 points. The author cannot verify their own version. - Rejected versions are never deleted. The next agent reads them with "petri digest" and does not try the same idea again. - Each change shows 3 results against its parent: score, tokens per task, and speed. Example: v2 raised the score from 5/20 to 19/20, but used 32% more tokens per task. New at ETHGlobal Tokyo: 1. ENSv2: every version is a name - Every tree, version and verifier is a real subname under petri.eth on Sepolia. A tree reads as model.harness.domain.petri.eth, for example v2.accepted.claude-sonnet-5.petri-harness-v1.coding.petri.eth. - Each tree has 3 folders: accepted, rejected and pending. When a version's status changes, its name moves to the new folder. - A version's text records hold its hypothesis, id, parent, score, gain, verifiers and token cost. Any ENS app can read them. 2. Propose: an author adds a version - The author runs the change in the Petri CLI, then submits it to the market from the web page. - A World ID human submits for free, 3 times a day, with a Selfie Check. - Without World ID, the author stakes 5 USDC. - The new version gets its name in the pending folder, with the author's claim for score, tokens and speed. 3. Verify: access that opens and closes on chain - A verifier joins with World ID (3 times the weight in the random pick) or with a 5 USDC stake (weight 1). - The picked verifier gets its own subname, verifier1.<version>, which expires after 10 minutes. The encrypted file key is sealed to it. - The resolver lets only that verifier's wallet write the vote record. The verifier signs the vote from its own wallet. Then the platform takes the right back. Every grant and revoke is an event on Sepolia, and the page links each transaction. 4. Intercepta: a clean wallet, and a safe payment - World ID proves one unique human. Intercepta proves the wallet has no record of scams, sanctions or blacklists. The platform checks the wallet before a stake, a free submit or a join. A flagged wallet gets no name and no access. - An AI agent can buy a version over x402 in Circle USDC. Before it signs, Intercepta screens the seller's wallet and the exact EIP-3009 authorization. A flagged seller never gets a signature. 5. Buy - A user pays 1 test USDC for an accepted version and gets their own subname for 30 days, with the file key sealed to them. The browser decrypts the harness files and downloads them as a zip. What works today: - Both trees and all their records are live on Sepolia. The tree page reads them from ENS. - Buy works in the browser with a real wallet. - Propose: the World ID Selfie Check and every ENS write are real. The CLI run shown before it is a demo. - Verify: the verifier name, the access grant, the vote and the revoke are real transactions on Sepolia. The World ID scan at join is a demo step. - A full round with a random pick of up to 5 verifiers runs on Sepolia from the terminal. - The agent buy over x402 with Intercepta is real, and settles in Circle USDC on Sepolia.

    How it's made

    Petri is TypeScript in 3 parts. The engine (Node 22, commander, zod, Anthropic SDK) runs the evolution. Each change may touch at most 2 files and 120 lines of its parent. It runs 20 coding tasks 5 times in a Node --permission sandbox that cannot see the tests. The result is saved as an ed25519-signed, hash-chained line in a JSONL log. One pure rule rebuilds every status from that log, and a version passes only when 2 other keys each measure at least +1000bp. The web app is Next.js 16, React 19, wagmi and viem. It reads the engine with "petri export", and the market streams each on-chain step to the page. ENSv2 is our public record and our access model. Every tree, version, verifier and buyer is a subname. Each name with children has its own UserRegistry, and one PermissionedResolver holds every record. The page reads them through the Universal Resolver. Access is a subname that expires, plus a resolver role scoped to one text key: grantSetterRoles opens the vote record for one wallet, and revokeRoles closes it. The harness files are encrypted with XChaCha20-Poly1305, and the key is sealed to each verifier or buyer with secp256k1 ECDH. World ID: IDKit Selfie Check on protocol 3.0 caps free submits at 3 a day per human. The proof's signal is the parent version, so it cannot submit another one. A verifier with World ID gets 3 times the weight in the pick. We also wrote the World ID for Agents device flow for verifiers. Intercepta works on both sides of a payment. On the agent's side, Quick Scan checks the seller's wallet, and Scan Message checks the exact EIP-712 authorization before the agent signs. On the platform's side, Quick Scan checks every wallet that stakes, submits or joins a round. Hacky parts: - The deployed ENSv2 contracts differ from the docs, so we pass DNS-encoded names to setText and call linkToRecord after every burn. - A version moves between folders by burning its name and registering it again. - The encrypted files live in ENS text records, a few KB per multicall. - The ENS explorer's indexer stopped during the event, so every name also writes a one-line summary to the standard name key, which the explorer always reads. - We run our own x402 facilitator inside the app, with our own relayer key, because the public x402.org facilitator does not serve Ethereum Sepolia. - Intercepta has no testnet data, so we screen each Sepolia address as its mainnet twin.