For Rust written by agents in Claude Code · Python backends by inter-opIn development

Vibe code it.
Prove it.

Agents write a growing share of code. rustproof is being built to prove that the Rust your agent writes does what it is supposed to do, and to keep it proven on every commit. Python services are designed to get the same treatment: pure decisions will be ported to Rust, called through a compiled extension, and proven.

Install the Claude Code plugin coming soonHow it works
Request early access coming soon
examples/fib-rs/src/lib.rsIllustrative walkthrough
01Claude writes fibHashMap: no Aeneas model
use std::collections::HashMap;
pub fn fib(n: u64) -> u64 {
fn go(n: u64, memo: &mut HashMap<u64, u64>) -> u64 {
if n < 2 {
return n;
}
if let Some(&v) = memo.get(&n) {
return v;
}
let v = go(n - 1, memo) + go(n - 2, memo);
memo.insert(n, v);
v
}
go(n, &mut HashMap::new())
}
02Patched at build timebrick memo-to-accumulator · −13 +12
pub fn fib(n: u64) -> u64 {
if n == 0 {
return 0;
}
let mut a: u64 = 0;
let mut b: u64 = 1;
let mut i: u64 = 1;
while i < n {
let next = a + b;
a = b;
b = next;
i += 1;
}
b
}
03A theorem, English firstthen Lean

For every 64-bit integer n where n ≤ 93, fib(n) returns the n-th Fibonacci number.

Preconditionn ≤ 93
.rustproof/specs/Fib.lean
def fib : Prop :=
∀ n : U64, n.val ≤ 93 →
∃ r, Generated.fib n = ok r ∧ r.val = fibSpec n.val
Found by the counterexample search

Found before the spec was proposed: fib(94) overflows u64. No unit test would say so.

04Checked by the Lean kernelend of the run
What a finished run records: a proof of Spec.fib with no sorry and only allowed axioms,
keyed to the hash of the patched tree that ships.
01 / THE PYTHON BACKEND

Prove the Python backend, too.

A Python service is designed to get the same treatment: rustproof will port its pure decisions to Rust, call them from Python through a compiled extension, and prove the Rust. By design, the proven code runs only inside the approved precondition; outside it, the original Python runs unchanged.

billing/prorate.pyIllustrative walkthrough
01A FastAPI billing handler calls thispure · type-hinted · no I/O
def prorate(amount_cents: int, days_used: int, days_in_period: int) -> int:
return amount_cents * days_used // days_in_period

rustproof python candidates finds it. The agent ports it with the port-python skill, straight into the provable subset.

02Ported, then patched with a guardPyO3 extension · maturin
.rustproof/crates/billing/src/lib.rs
pub fn prorate(amount_cents: u64, days_used: u64, days_in_period: u64) -> u64 {
amount_cents * days_used / days_in_period
}
billing/prorate.py (patched)
from rustproof_ext.billing import prorate as _prorate_rs
U64_MAX = 18_446_744_073_709_551_615
def _prorate_ok(a: int, u: int, d: int) -> bool: # generated from the approved spec
return (
type(a) is int and type(u) is int and type(d) is int
and 0 < d <= U64_MAX
and 0 <= u <= d
and 0 <= a <= U64_MAX
and a * u <= U64_MAX
)
def prorate(amount_cents: int, days_used: int, days_in_period: int) -> int:
if _prorate_ok(amount_cents, days_used, days_in_period):
return _prorate_rs(amount_cents, days_used, days_in_period) # proven
return amount_cents * days_used // days_in_period # original
03A theorem about the RustEnglish first, then Lean

For integer amounts and periods that fit in 64 bits, where the period is at least one day, the days used don’t exceed it, and amount × days used fits in 64 bits, prorate returns at most the amount.

.rustproof/specs/Prorate.lean
def prorate : Prop :=
∀ a u d : U64, 0 < d.val → u.val ≤ d.val → a.val * u.val ≤ U64.max →
∃ r, Generated.prorate a u d = ok r ∧ r.val ≤ a.val
Found by the counterexample search

Found before the spec was proposed: prorate(100, 1, 0) divides by zero. The handler never checked.

04Checked by the Lean kernelend of the run
Spec.prorate: a customer is never charged more than the full amount.
After rustproof build, the API calls the proven Rust inside the precondition and the original Python outside it.
1
Find candidates
rustproof python candidates is designed to list pure, fully type-hinted spans with no I/O, no globals and no exceptions crossing the boundary.
2
Port and patch
The port will be Rust under .rustproof/crates/, written in the provable subset. The patch is designed to replace the Python body with a call into the extension, guarded by the approved precondition.
3
Differential tests across the boundary
Generated inputs; both versions must agree, or both must fail. Every port will be timed, and one slower than the Python it replaces flagged.
4
What this example surfaces
A zero-day period divides by zero; a large amount over a long period overflows 64 bits. Decide: a 400 at the API boundary, or keep the guarded fallback.
02 / THE AHA

The theorem catches what the tests miss.

fib(10) == 55 passes. So does fib(93). The theorem cannot hold for all of u64, and the counterexample search is designed to say why.

fib(93)12,200,160,415,121,876,738fits in u64
fib(94)19,740,274,219,868,223,167overflows u64
preconditionn.val ≤ 93

This is the spec review moment: the developer reads one sentence of English and chooses. Every option is legitimate; the system is designed to force the decision instead of hiding it.

a
Accept the precondition
Guard it at the boundary. Callers get an error for n > 93.
b
Widen the type
u128 is good up to fib(186). Re-prove.
c
Make overflow explicit
checked_add, return Option<u64>, handle None.
03 / DOGFOOD

The plan: rustproof proves rustproof.

rustproof’s own decisions are written so that rustproof can prove them. These are the first properties we will prove. None is proven yet.

check_conclusion · a failing, counterexample or stale obligation never yields successcrates/rustproof-corePlanned
next_status · a function is proven only if its spec is approved and its proof checked; a source-hash change always yields stalecrates/rustproof-corePlanned
policy_verdict · any sorry or disallowed axiom fails policycrates/rustproof-corePlanned
can_approve · someone who is not an approver for a spec’s path can never approve itpackages/platform-core, via Python inter-opPlanned
quota_decision · a run never starts over quotapackages/platform-core, via Python inter-opPlanned
04 / THE PIPELINE

Prove whenever possible. Test the rest.

Code that can be proven is designed to be patched into the subset Aeneas accepts, extracted to Lean 4, given a theorem, and proven by Leanstral. By design, I/O, the network, the clock and unsafe code stay outside the boundary and are covered by tests.

Rust · PythonYour workspacea Cargo workspace, or a Python service with pure decisions
PatchBricksinto the provable subset
ExtractCharon → Aeneaspure functions in Lean 4
SpecTheoremplain English, then Lean
ProveLeanstralparallel search, in the cloud
CheckLean kerneldeterministic, local
ExcludedI/O, unsafe, asynccovered by tests, shown with a reason

When the code after an I/O call takes the result as an argument, the theorem holds for every possible response. That is stronger than any mock.

05 / THE TRUST MODEL

Specs are the review surface. Proofs are not.

The proven code is the running code

rustproof is designed to prove the patched tree, and the patched tree is what gets compiled and shipped. Proofs will be keyed to its hash, and release artifacts stamped with it.

Humans read theorems, never proofs

The Lean kernel rejects every invalid proof, so proof generation can be fully automated. By design, nothing checks a spec except a person, in plain English first.

Patches are visible, tested, reversible

Every patch is designed to be a before/after diff in Claude Code, the PR and the dashboard. Both sides compile, so they can run on the same generated inputs. Rejecting one takes the function out of the proof boundary.

No escape hatches

The build is designed to fail on sorry, on any axiom outside the approved set, and on any proof that relies on unchecked evaluation. Overflow checks are designed to stay on in release, so the binary matches the model.

07 / START

Three steps, inside Claude Code.

1Install the pluginInstall the Claude Code plugin coming soon

Will bundle the CLI, hooks, Lean’s language server and the mod.

2Log in/rustproof:login coming soon

Browser sign-in, with sign-up in the same flow. The token is designed to live in your OS keychain.

3Scan the workspace/rustproof:init coming soon

Will classify every function as provable, patchable or excluded, with the reason.

No more “trust me bro.”

The goal: a build whose proven functions are proven against the exact code in that build.

Install the Claude Code plugin coming soonRequest early access coming soon