agentleFS
a16za16z/jolt/CLAUDE.md

jolt

CLAUDE.md1.1k starsChanged 13 days agoApache-2.0View on GitHub

Jolt is a zkVM (zero-knowledge virtual machine) for RISC-V (RV64IMAC) that efficiently proves and verifies program execution. It uses sumcheck-based protocols, multilinear polynomial commitments (Dory), and the Twist/Shout lookup argument.

  • Installs packages

We split this CLAUDE.md into the rules it gives an agent

17 rules. About 0 are common, 8 are distinctive, and 9 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈8

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 9

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Read relevant code before asking about repository facts.

    line 11
  2. Distinctive:

    Treat follow-up messages as updates to the active task unless the user cancels or replaces it.

    line 12
  3. Very specific:

    After stage 8, jolt-prover/src/blindfold.rs replays the assembled shell through the verifier's own stages and lowers those outputs with …

    line 164
  4. Very specific:

    Use #[inline] judiciously in hot paths

    line 181
  5. Distinctive:

    Keep compact witness values in their native scalar types until field arithmetic is required.

    line 188
  6. Very specific:

    Use non_snake_case for math variables: log_T, ram_K, log_K, etc.

    line 193
  7. Distinctive:

    No public API, abstraction, mode, or state container without an in-repo production caller or documented external contract.

    line 204
  8. Very specific:

    Add cfg/cfg_attr gates only where the build requires them.

    line 207
  9. Distinctive:

    Add tests for distinct failure signals beyond existing tests, golden fixtures, verifier fixtures, or CI.

    line 211
  10. Very specific:

    No old-vs-new equivalence tests and no #[cfg(test)] copy of superseded code kept as the oracle.

    line 213
  11. Distinctive:

    Before PR handoff, audit every added test and helper.

    line 214
  12. Very specific:

    Use #[expect(clippy::...)] on test modules to blanket-suppress test-inappropriate lints rather than per-function annotations

    line 223
  13. Distinctive:

    Keep comment density low; a comment must carry information the code cannot (except required legal headers and tool directives).

    line 227
  14. Distinctive:

    Keep invariants/contracts the types cannot express, naming enforcement.

    line 228
  15. Very specific:

    Keep soundness/security reasoning, SAFETY: on unsafe, and behavior forced by an external dependency, platform, or protocol.

    line 229
  16. Very specific:

    Keep public API contracts and algorithm explanations (paper/spec links where applicable).

    line 230
  17. Distinctive:

    Delete narration of code or assertions, section banners, commented-out code, stale descriptions, and history/migration notes.

    line 231

≈ “Common” is an estimate: at least 1 in 5 of the 25,680 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
CLAUDE.md

CLAUDE.md

Project Overview

Jolt is a zkVM (zero-knowledge virtual machine) for RISC-V (RV64IMAC) that efficiently proves and verifies program execution. It uses sumcheck-based protocols, multilinear polynomial commitments (Dory), and the Twist/Shout lookup argument.

Agent Workflow

  • Carry an authorized request through implementation and verification. Resolve routine choices from repository conventions; ask only when missing information would materially change correctness or scope. Continue independent work while an answer is pending.
  • User instructions take precedence over skill guidance. Reuse authorization and answers already supplied. If a skill blocks requested work, cite its exact file and instruction and explain the conflict.
  • Read relevant code before asking about repository facts. Use rg for searches; batch independent reads when supported, and wait for required results before dependent work. Run Cargo commands sequentially, including across agents.
  • Treat follow-up messages as updates to the active task unless the user cancels or replaces it.
  • Lead with the result. Keep explanations concise and concrete; report checks actually run, their results, and any remaining blocker. Preserve required output formats in automated workflows.

Essential Commands

Linting and Formatting

# Must pass in both standard and ZK modes
cargo clippy --all --features host -q --all-targets -- -D warnings
cargo clippy --all --features host,zk -q --all-targets -- -D warnings
cargo fmt -q

Testing

# Always cargo nextest, never cargo test
cargo nextest run --cargo-quiet

# Run specific test in specific package
cargo nextest run -p [package_name] [test_name] --cargo-quiet

# Guest x mode acceptance matrix (crates/jolt-prover/tests/e2e_matrix.rs): one
# table per instruction profile, proven in clear, ZK, and Akita modes in CI.
# Ordinary profile: ten guest cases.
cargo nextest run -p jolt-prover --features prover-fixtures -E 'binary(e2e_matrix)' --cargo-quiet
cargo nextest run -p jolt-prover --features prover-fixtures,zk -E 'binary(e2e_matrix)' --cargo-quiet
cargo nextest run -p jolt-prover --features akita,prover-fixtures -E 'binary(e2e_matrix)' --cargo-quiet

# Field-inline profile: field_ops, field_limbs, and muldiv.
cargo nextest run -p jolt-prover --features prover-fixtures,field-inline -E 'binary(e2e_matrix)' --cargo-quiet
cargo nextest run -p jolt-prover --features prover-fixtures,field-inline,zk -E 'binary(e2e_matrix)' --cargo-quiet
cargo nextest run -p jolt-prover --features prover-fixtures,field-inline,akita -E 'binary(e2e_matrix)' --cargo-quiet

# Full prover suites and the verifier fixtures (mirror CI)
cargo nextest run -p jolt-verifier standard_muldiv --features prover-fixtures --cargo-quiet
cargo nextest run -p jolt-prover --features prover-fixtures --cargo-quiet
cargo nextest run -p jolt-prover --features prover-fixtures,zk --cargo-quiet
cargo nextest run -p jolt-prover --features akita,prover-fixtures --cargo-quiet

Building

# Prefer clippy over build for validation. Only build when preparing to execute a binary.
cargo build -p jolt-prover -q

# After pulling changes, reinstall the jolt CLI or guest builds may fail.
cargo install --path . --locked

Profiling

# Modular prover (primary): emits benchmark-runs/{timestamp}_modular_{name}_{scale}/ containing trace.json
# (Perfetto UI / trace_processor SQL), summary.json (machine-queryable), and memory.html,
# with benchmark-runs/latest_modular_{name}_{scale} symlinked to the newest successful run.
cargo run --release -p jolt-prover --features profiling -- profile --name fibonacci --format chrome
# --name options (default scale): fibonacci (16), sha2-chain (22), sha3-chain (22), btreemap (20)
# --scale <log2 trace length> overrides; --format none = no-subscriber Instant baseline
# --backend reference (default, naive test oracle) | optimized (performance tier);
# optimized artifacts get an _optimized suffix on the run dir and latest_ symlink

# Canonical summary queries (no Perfetto UI needed) — see book/src/usage/profiling/zkvm_profiling.md
jq '.stages | map({label, s: (.wall_time_ns/1e9)})' benchmark-runs/latest_modular_fibonacci_16/summary.json
jq '.spans | to_entries | sort_by(-.value.total_ns) | .[:10]' benchmark-runs/latest_modular_fibonacci_16/summary.json

# Multi-scale sweep (one profile subprocess per run; results in benchmark-runs/modular_timings.csv,
# rendered by scripts/benchmark_summary.py, plot_benchmarks.py, plot_memory_usage.py)
cargo run --release -p jolt-prover --features profiling -- benchmark --min-scale 18 --max-scale 21 --resume

# Per-batch heap snapshots (*.folded in the run directory, exact bytes; totals in summary.json's .heap; rendered by memory.html)
cargo run --release -p jolt-prover --features profiling,allocative -- profile --name fibonacci --format chrome

# jolt-eval telemetry objectives over the same summary (grammar: telemetry:<workload>:<metric>)
cargo run -p jolt-eval --bin measure-objectives -- --objective telemetry:fibonacci:prover_time_s

The span taxonomy (versioned, normative) lives in crates/jolt-profiling/src/taxonomy.rs — renaming a span is a schema change (summary keys and telemetry:* objectives break; the profiling smoke test enforces label presence, but it is not yet CI-wired — run it explicitly after taxonomy changes, see the NOTE in .github/workflows/rust.yml).

Architecture

Crate Structure

The proof system is split into focused crates under crates/. Top-level crates include tracer, jolt-sdk, jolt-inlines, and common.

Arkworks dependencies use a fork: a16z/arkworks-algebra branch dev/twist-shout, pinned in the root Cargo.toml.

jolt-prover — Prover orchestration for the staged Jolt protocol; Dory is the default PCS, akita selects the native lattice batching path, and zk enables BlindFold.

jolt-verifier / jolt-claims — Verifier staging and the symbolic protocol relations shared with the prover.

jolt-kernels / jolt-witness — Reference and optimized prover kernels plus trace-backed witness construction.

jolt-host / jolt-program — Guest builds, tracing entry points, bytecode expansion, and shared program preprocessing.

jolt-field / jolt-poly / jolt-sumcheck / jolt-openings — Field, polynomial, sumcheck, and PCS abstractions.

tracer — RISC-V emulator producing execution traces (Cycle per instruction)

jolt-sdk — #[jolt::provable] macro generating prove/verify/analyze/preprocess functions

jolt-inlines — Optimized cryptographic primitives (sha2, blake3, bigint, secp256k1, etc.) replacing guest-side computation with efficient constraint-native implementations

common — Shared constants (XLEN, REGISTER_COUNT, thresholds) and JoltDevice/MemoryLayout types

The SDK's host feature enables native build/prove APIs. On jolt-prover, akita selects the native lattice batching protocol and is mutually exclusive with zk.

Key Type Parameters

The staged prover and verifier are generic over the PCS, vector commitment, and transcript. Dory uses Fr; the akita build uses AkitaField.

PCS: CommitmentScheme
VC: VectorCommitment<Field = PCS::Field>
T: Transcript<Challenge = PCS::Field>

Prover Pipeline

  1. Preprocess: jolt-program expands bytecode and builds the program/RAM view; the selected PCS builds prover and verifier preprocessing.
  2. Trace and witness: jolt-host/tracer execute the guest; jolt-witness exposes trace-backed committed and virtual polynomials.
  3. Commit: stage 0 commits the trace objects. Dory streams individual polynomials; Akita commits the one-hot columns as one native group and auxiliary objects separately.
  4. Reduce: jolt-prover/src/stages/ proves stages 1–7 from the symbolic relations in jolt-claims.
  5. Open: stage 8 reduces the remaining claims and dispatches the joint PCS opening.
  6. BlindFold: ZK builds prove the committed sumcheck transcript with jolt-blindfold.

Protocol Ownership

  • jolt-claims owns relation IDs, opening geometry, protocol dimensions, and every symbolic input/output expression.
  • jolt-verifier owns proof/preprocessing wire types, transcript validation, and the stage verifier.
  • jolt-prover owns proving orchestration and backend-specific stage 0/stage 8 integration; it consumes the shared claims rather than restating verifier formulas.
  • jolt-witness owns trace-backed witness construction. jolt-kernels owns reference and optimized evaluation kernels.
  • jolt-poly, jolt-sumcheck, jolt-openings, jolt-dory, and jolt-akita own the reusable polynomial, sumcheck, and PCS layers.
  • jolt-claims owns the RV64 and field-inline constraint tables and variable layout under protocols::composed::r1cs; jolt-r1cs owns the generic builder and matrix layer. jolt-blindfold owns the generic zero-knowledge proof over recorded sumchecks.

Committed trace polynomials are identified by JoltCommittedPolynomial; virtual polynomials by JoltVirtualPolynomial. Do not recreate their ordering or opening points outside jolt-claims.

ZK Feature Gate

The zk feature selects committed sumcheck recorders and the BlindFold tail at compile time. Clear proofs carry JoltProofClaims::Clear; ZK proofs carry JoltProofClaims::Zk. JoltProof::protocol still self-describes the mode, and the verifier rejects a build/proof mismatch.

jolt-prover/src/recorder.rs is the mode seam. Stage recipes are shared: clear recorders expose round polynomials, while ZK recorders retain committed witnesses. After stage 8, jolt-prover/src/blindfold.rs replays the assembled shell through the verifier's own stages and lowers those outputs with jolt-verifier/src/stages/zk/. It checks that the replay transcript exactly equals the forward prover transcript before constructing the BlindFold witness.

Critical invariant: a relation's input and output expressions have one owner in jolt-claims. Prover evaluation, verifier checking, and BlindFold lowering must all consume those expressions. Never add a parallel claim formula for one mode. Changes to stage order, public-value derivation, or transcript absorption require clear, ZK, and verifier-fixture tests.

Development Guidelines

Performance

  • Profile before optimizing
  • Benchmark changes to poly/ code — small regressions multiply across thousands of sumcheck rounds
  • Use #[inline] judiciously in hot paths
  • Pre-allocate vectors unsafely when size is known; avoid clones in hot paths
  • Hot trace paths get one pass and one owner of trace-sized storage. Produce or share derived rows during the existing pass instead of walking or materializing the trace again.

Prover Hot Paths

  • Sumcheck inner loop dominates: polynomial bind, sumcheck_evals, eq_poly evals
  • Keep compact witness values in their native scalar types until field arithmetic is required.
  • Preserve the shared lazy-RA kernels; do not materialize one dense field vector per RA polynomial.

Code Style Invariants

  • Use non_snake_case for math variables: log_T, ram_K, log_K, etc.
  • Machine-checked, repo-wide: one cfg_attr per predicate per item; fold adjacent #[cfg_attr(P, A)] #[cfg_attr(P, B)] into #[cfg_attr(P, A, B)].
  • Machine-checked, repo-wide: #[allocative(visit = ...)] never decorates a container of primitives (Vec<u32>, Vec<Vec<usize>>, Vec<Option<u8>>, ...) or of field elements (Vec<F>, Vec<Vec<F>>, [Vec<F>; N]). Native impls report element types and unused capacity, and JoltField: MaybeAllocative makes them reachable for every scalar table. In-crate element types built from primitives and F derive Allocative; jolt_kernels::backend::visit_heap_free_elements is only for element types that own no heap but carry no Allocative impl — the witness rows, selectors, opening ids, and prefix evaluations whose jolt-claims, jolt-lookup-tables, and jolt-witness types would gain the derive for nothing.
  • Machine-checked on added lines: import types, traits, enums, constants, and PascalCase macros; reference them by short name. Keep enum variants qualified by the imported enum type (Kind::ADD, not bare ADD). Import singleton paths directly (use x::Kind, never use x::Kind::{self}). Lowercase namespace free functions and macros (std::mem::take, tracing::info!) may stay qualified. Fully qualified paths remain valid for ambiguity, attribute arguments (allocative(visit = crate::backend::visit_heap_free_elements)), and macro bodies. Once a path is imported, never spell it qualified in the same file.
  • Alias an instruction-kind enum as Kind at emitter call sites and write Kind::INSTRUCTION; never qualify emitted instructions with SourceInstructionKind, JoltInstructionKind, or a module path.
  • Give each protocol formula, geometry or sizing law, schedule, and state transition one owner. Consumers call the canonical implementation instead of mirroring or open-coding it. Tests use independent ground truth or the production computation; never a second implementation of the same rule as their oracle.
  • Encode correlated state and absence with typed requests, structs, enums, and Option; never value sentinels, decomposed arguments, or parallel options that can disagree.
  • Serialized or ordinal enums are append-only; keep feature-gated and test-only variants last so feature selection cannot shift real discriminants.
  • Enforce public-boundary invariants at the point of fault in release builds with typed errors. Use debug_assert only for properties already pinned by types or release checks; keep recoverable capability gaps separate from invariant violations.
  • Derive trait impls instead of hand-rolling; exhaust derive escapes (#[allocative(bound = "F: JoltField")], visit = ..., skip) first. Hand-write only what a derive cannot express, keep it local to the one type that needs it, and size buffers by capacity(), not len().
  • A free function is pure or shared across ≥2 callers. Otherwise make it a method on the type whose state it uses; inline it when no type owns the behavior.
  • No public API, abstraction, mode, or state container without an in-repo production caller or documented external contract; add it with its first use. Lazy-init globals and error slots are valid, but speculative lifecycle guards and unreachable transitions are not.
  • State enforcement honestly in docs: never describe a property as constraint-enforced when it holds only for the honest encoder or under a debug_assert; name the mechanism and location that pins each invariant. If reviewers independently misread a deliberate gap, the missing argument belongs in a comment.
  • Make names track current semantics: rename vocabulary when an encoding changes (UnsignedIncMsb → BalancedIncCarry); keep no compatibility names.
  • Add cfg/cfg_attr gates only where the build requires them.

Tests

  • Add tests for distinct failure signals beyond existing tests, golden fixtures, verifier fixtures, or CI; no test required for every low-impact edit. Prefer one focused test per stated behavior.
  • Permanent tests assert against independent ground truth: spec vectors, frozen wire digests, verifier fixtures, jolt-kernels' reference tier, or algebraic properties. Never a second implementation of the rule under test.
  • No old-vs-new equivalence tests and no #[cfg(test)] copy of superseded code kept as the oracle; transition validation belongs in the PR, not the suite.
  • Before PR handoff, audit every added test and helper; remove development-only probes, ignored tests without a documented run condition, temporary benchmarks, diagnostic counters or histograms, and one-off parity or fuzz scaffolding. A worthwhile manual diagnostic becomes a tool or benchmark with a documented command.
  • Match verification to changed behavior and complete applicable checks above and in the invoked workflow. Locally select affected Rust tests with cargo nextest run -p <crate> --cargo-quiet -E 'test(<name>)' and required features; Python: uv run python -m unittest scripts.tests.<module> -v. Full suites run in CI; broaden passed checks only for further changes, failures, or unresolved concerns.
  • Cleanup pass on a diff: .claude/skills/test-policy/SKILL.md.

Lint Policy

  • Workspace enforces allow_attributes = "deny" — use #[expect(...)] instead of #[allow(...)]
  • The jolt-verifier runtime closure (20 crates, listed in specs/verifier-closure-lints.md) carries stricter crate-root lints: panic-source denies (indexing_slicing in control-plane crates, panic_in_result_fn, wildcard_enum_match_arm, ...), forbid(unsafe_code) where a crate has no unsafe, and numeric-discipline denies in jolt-verifier itself — which additionally denies unreachable, the only abort macro that neither panic nor panic_in_result_fn denies. New code in those crates must fix the lint or add #[expect(clippy::..., reason = "...")] at the narrowest scope with a real justification
  • .unwrap() and .expect() are fine in tests. In non-test code, avoid them unless the alternative significantly hurts readability (e.g., infallible fixed-size array conversions). When used, annotate the function with #[expect(clippy::unwrap_used)] or #[expect(clippy::expect_used)]
  • Use #[expect(clippy::...)] on test modules to blanket-suppress test-inappropriate lints rather than per-function annotations

Comments

  • Keep comment density low; a comment must carry information the code cannot (except required legal headers and tool directives).
  • Keep invariants/contracts the types cannot express, naming enforcement; why-not notes and non-obvious warnings preventing bugs; non-local coupling pointers.
  • Keep soundness/security reasoning, SAFETY: on unsafe, and behavior forced by an external dependency, platform, or protocol.
  • Keep public API contracts and algorithm explanations (paper/spec links where applicable); issue/RFC links and TODO(#issue) only when they explain a constraint.
  • Delete narration of code or assertions, section banners, commented-out code, stale descriptions, and history/migration notes. Refactor confusing code in implementation work; cleanup passes only flag it.
  • Judge lint suppressions under Lint Policy above; a justification must be verified, not merely stated. Cleanup procedure and keep criteria: .claude/skills/comment-policy/SKILL.md.

Download now (ZIP)

Trending

More talk lately.about the whole repository

Dec 2025: 0 mentionsJan 2026: 0 mentionsFeb 2026: 2 mentionsMar 2026: 0 mentionsApr 2026: 1 mentionMay 2026: 5 mentionsJun 2026: 0 mentionsJul 2026: 3 mentionsAug 2026: 1 mentionSep 2026: 3 mentionsOct 2026: 3 mentionsNov 2026: 0 mentions
Dec 2025Jun 2026Nov 2026
Mentions a month of the a16z/jolt repository that our weekly crawl found. There is no adoption data for this file yet.

Who's talking about a16z/jolt

The biggest 5 of 33 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 33

Talked about on GitHub (33 times).

On GitHub · 33

28 more on GitHub

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.