Veridict

AI writes the code.
Math approves the merge.

Veridict is a merge gate for synthesized code. Three formal proofs verify the PR. One ZK signature authorizes it. Zero identities revealed.

Vibe-coded code shouldn't merge on vibes.
It should merge on proof.

Why we built this

Open source is leaking trust.

Four incidents. One pattern. The same architectural hole shows up over and over again, in projects that have nothing else in common.

bincode · 2024

One maintainer rewrote git history while migrating off GitHub. The community asked questions. The questions became doxxing. The project shut down permanently. There is no 1.3.4.

r/rust thread →
xz-utils · 2024

"Jia Tan" earned maintainer status over two years, then shipped a backdoor that nearly compromised sshd on every major Linux distro. Caught by accident, weeks before stable release.

post-mortem →
curl · 2024

"My job is increasingly fact-checking the AI," wrote Daniel Stenberg. Open-source maintainers are drowning in plausible AI PRs that pass surface checks and fail on invariants.

Stenberg's blog →
vibe-coding · 2025

Karpathy coined it. The hackathon brief quoted the discomfort: "we have no way of knowing if what we're vibecoding does what we think it does." The practice went mainstream anyway.

hackathon brief →
Different incidents. Same shape. Identity-coupled trust at the centre, no formal gate before approval, and reviewers paying the cost in burnout, doxxing, or undetected backdoors.
The flow

Three steps. One signature.

No checklists. No vibes. Each PR walks the same path from English spec to anonymous merge approval, and the issuer refuses to sign if any of the three formal layers fails.

01 / Synthesis

Spec in. Three artifacts out.

Claude turns your spec into an implementation, a pytest suite, and a Z3 invariant file. The bot opens the PR for you.

02 / Verification

Three layers. No vibes.

mypy checks types. pytest checks behaviour. Z3 checks invariants symbolically. Any failure → no credential.

03 / Anonymous Approval

ZK proof in ~10s.

A Longfellow proof replaces your identity with a stable per-PR pseudonym. N proofs land → merge button unlocks.

Spec
English
Synth
Claude
Verify
mypy · pytest · z3
Credential
MDOC bound to SHA
ZK Proof
Longfellow · 10s
Merge
Gate unlocks
Verification, in the open

If the spec doesn't hold, no proof exists.

The issuer runs mypy, pytest, and Z3 against the PR before minting a credential. Failures break the chain. There is no "force-approve."

issuer.spec_check · PR #11
$ veridict verify pull/11→ fetching files@a8c4f2…✓ mypy      0 errors✓ pytest    14 passed in 0.34s✓ z3        all invariants UNSAT for negation credential issued → valid 10mbound to a8c4f2 · role=maintainer

ZK Proof Receipt verified

circuit_id3f8c…0192
size361,408 bytes
prover10.4 s
verifier7.1 s
transcript8217d4…ae5b
pseudonym@reviewer-a7c2f3
identitynever disclosed
Anonymity, by construction

Reviewers prove. Identities disappear.

Every approval is a 360 KB Longfellow proof that you hold a credential. The PR author, the bot, and the audit trail see a pseudonym, not a face. The proof, not the person, speaks.

Trust model

Who sees what.

Anonymity is toward the verifier: CI, the PR author, and the audit trail. The issuer still sees your OAuth identity at credential time. We say so out loud.

Reviewer

  • Own credential, own proof
  • Spec-check result for the PR
  • Other reviewers' identities

Issuer

  • OAuth identity (credential time)
  • Spec-check result
  • How reviewers voted

Verifier / Backend

  • Proofs, pseudonyms, approval counts
  • Posts bot comments + commit status
  • Reviewer identities

PR author + GitHub UI

  • Pseudonyms + reputation chips
  • Commit status (N / required)
  • Reviewer identities
What this isn't

We don't pretend to be production.

A weekend prototype is allowed limits, as long as it names them. Here are ours.

Anonymity

No nullifier yet.

A reviewer with two sessions can sign two approvals on one PR. They look like two pseudonyms. Production fix: derive a blinded ID inside the ZK circuit.

Key custody

Issuer mints the device key.

For demo speed. A real deployment would generate the device key in the browser so the issuer never sees it.

Spec coverage

Python only, for now.

mypy + pytest + Z3 only run on .py files. Non-Python PRs pass through unverified. Dafny, Rust, Lean are obvious next stops.

Comments

Single bot account.

Every anonymous approval posts as @anonymous-review-bot. Pseudonyms + identicons inside the comment do the distinguishing.

Sign in. Approve. Disappear.

Try Veridict on a real PR. The demo repo is wired up with branch protection, and your anonymous approval flips the gate.

Sign in with GitHub
built in 72 hours by Sumit · solo · no caffeine spared