Skip to content

Commit b278193

Browse files
committed
chore: improve CLI help and clean up lints
Add clearer clap help text and CLI help assertions.\nDocument the full fmt/clippy/test verification flow in the project docs.\nRefactor STARK and runtime support code to satisfy rustfmt and clippy without changing behavior.
1 parent b05d543 commit b278193

21 files changed

+253
-163
lines changed

CLAUDE.md

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ llm-provable-computer is an implemented Rust workspace for a deterministic trans
1919
<status>
2020
- Milestone 1: complete.
2121
- Milestone 2: complete for the current proof scope.
22-
- Verified locally on 2026-03-18:
23-
- `cargo test`
24-
- `cargo test --features full`
22+
- Verified locally on 2026-03-19:
23+
- `cargo fmt --all --check`
24+
- `cargo clippy --all-targets --all-features -- -D warnings`
25+
- `cargo test --all-features`
2526
- Current vanilla STARK scope:
2627
- supported: `NOP`, `LOADI`, `LOAD`, `STORE`, `PUSH`, `POP`, `ADD`, `ADDM`, `SUB`, `SUBM`, `MUL`, `MULM`, `CALL`, `RET`, `JMP`, `JZ`, `JNZ`, `HALT`
2728
- rejected: softmax and hard-softmax proof paths, bitwise instructions, compare instructions, non-halted public claims, public claims with `carry_flag = true`
@@ -36,7 +37,6 @@ Cargo.toml
3637
Cargo.lock
3738
README.md
3839
CLAUDE.md
39-
LICENSE
4040
src/
4141
assembly.rs # .tvm parser, directives, labels
4242
compiler.rs # ProgramCompiler
@@ -74,14 +74,16 @@ scripts/
7474
| Inventory files | `rg --files` | Fastest repo scan |
7575
| Check repo state | `git status --short` | Separate your edits from unrelated files |
7676
| Run default suite | `cargo test` | Core milestone-1 and milestone-2 validation |
77-
| Run full engine suite | `cargo test --features full` | Burn + ONNX + Python validator + CLI workflow |
77+
| Check formatting | `cargo fmt --all --check` | Matches CI-ready rustfmt output |
78+
| Run strict lint pass | `cargo clippy --all-targets --all-features -- -D warnings` | Keep the full tree warning-free |
79+
| Run full engine suite | `cargo test --all-features` | Burn + ONNX + Python validator + CLI workflow |
7880
| Run a program | `cargo run --bin tvm -- programs/fibonacci.tvm` | Shortcut for `tvm run` |
7981
| Trace execution | `cargo run --bin tvm -- run programs/counter.tvm --trace` | Emits trace and summary |
8082
| Verify transformer vs native | `cargo run --bin tvm -- run programs/fibonacci.tvm --verify-native` | Lockstep comparison |
8183
| Verify all engines | `cargo run --features full --bin tvm -- run programs/fibonacci.tvm --verify-all` | Transformer + native + Burn + ONNX |
8284
| Create a proof | `cargo run --bin tvm -- prove-stark programs/fibonacci.tvm -o /tmp/fib.proof.json` | Uses current vanilla STARK path |
8385
| Verify a proof | `cargo run --bin tvm -- verify-stark /tmp/fib.proof.json` | Re-checks a saved proof |
84-
| Review doc drift | `git diff -- README.md SPEC.md IMPLEMENTATION_PLAN.md CLAUDE.md` | Use before finishing doc/context work |
86+
| Review doc drift | `git diff -- README.md CLAUDE.md docs/` | Use before finishing doc/context work |
8587
</commands>
8688

8789
<workflows>
@@ -94,8 +96,8 @@ scripts/
9496

9597
<proof_change>
9698
1. Read `src/proof.rs` and `src/vanillastark/**`.
97-
2. Update support and limitation language in `SPEC.md` and `README.md`.
98-
3. Re-run at least `cargo test` and, when Burn or ONNX paths are affected, `cargo test --features full`.
99+
2. Update support and limitation language in `README.md`, `CLAUDE.md`, and matching files under `docs/`.
100+
3. Re-run at least `cargo test` and, when Burn or ONNX paths are affected, `cargo test --all-features`.
99101
</proof_change>
100102

101103
<engine_change>
@@ -123,7 +125,7 @@ scripts/
123125
|---------|--------------|-----|
124126
| `prove-stark` rejects a program | Unsupported instruction, attention mode, or claim shape | Check `src/proof.rs::validate_proof_inputs` and the carry/halted restrictions |
125127
| Burn or ONNX commands are unavailable | Missing feature flag | Re-run with `--features burn-model`, `--features onnx-export`, or `--features full` |
126-
| Docs mention WASM compilation as current behavior | Stale pre-implementation text | Prefer `SPEC.md` and the source tree over old planning language |
128+
| Docs mention WASM compilation as current behavior | Stale pre-implementation text | Prefer `README.md`, `CLAUDE.md`, and the source tree over old planning language |
127129
| An engine mismatch appears during verification | Trace divergence across runtimes | Inspect `ExecutionTraceEntry` output and compare instruction/state pairs |
128130
</known_issues>
129131
</troubleshooting>

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,21 @@ cargo test --features full # Everything
304304
cargo bench # Hull + STARK benchmarks
305305
```
306306

307+
## Development Checks
308+
309+
```bash
310+
cargo fmt --all --check
311+
cargo clippy --all-targets --all-features -- -D warnings
312+
cargo test --all-features
313+
```
314+
315+
The CLI is self-documenting:
316+
317+
```bash
318+
cargo run --bin tvm -- --help
319+
cargo run --bin tvm -- run --help
320+
```
321+
307322
---
308323

309324
## Repository Structure

benches/hull_benchmark.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
2-
use rand::{rngs::StdRng, Rng, SeedableRng};
32
use llm_provable_computer::HullKvCache;
3+
use rand::{rngs::StdRng, Rng, SeedableRng};
44

55
fn bench_query_scaling(c: &mut Criterion) {
66
let mut group = c.benchmark_group("hull_query_vs_bruteforce");

src/bin/tvm.rs

Lines changed: 68 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -26,87 +26,120 @@ use llm_provable_computer::{BurnExecutionRuntime, BurnTransformerVm};
2626
type CliBurnBackend = NdArray<f64>;
2727

2828
#[derive(Debug, Parser)]
29-
#[command(name = "tvm", about = "Run deterministic llm-provable-computer programs.")]
29+
#[command(
30+
name = "tvm",
31+
about = "Run deterministic llm-provable-computer programs."
32+
)]
3033
struct Cli {
3134
#[command(subcommand)]
3235
command: Command,
3336
}
3437

3538
#[derive(Debug, Subcommand)]
3639
enum Command {
40+
/// Run a program and print the final machine state.
3741
Run {
42+
/// Path to the source `.tvm` program.
3843
program: PathBuf,
44+
/// Maximum number of execution steps before stopping.
3945
#[arg(long, default_value_t = 512)]
4046
max_steps: usize,
47+
/// Emit the full step-by-step execution trace.
4148
#[arg(long)]
4249
trace: bool,
50+
/// Number of transformer layers to distribute instructions across.
4351
#[arg(long, default_value_t = 1)]
4452
layers: usize,
53+
/// Execution backend to use for the run.
4554
#[arg(
4655
long,
4756
default_value = "transformer",
4857
value_parser = parse_execution_engine
4958
)]
5059
engine: CliExecutionEngine,
60+
/// Verify the transformer runtime against the native interpreter.
5161
#[arg(long)]
5262
verify_native: bool,
63+
/// Verify the transformer and native runtimes against Burn.
5364
#[arg(long)]
5465
verify_burn: bool,
66+
/// Verify the transformer and native runtimes against ONNX.
5567
#[arg(long)]
5668
verify_onnx: bool,
69+
/// Verify all available runtimes in lockstep.
5770
#[arg(long, conflicts_with_all = ["verify_native", "verify_burn", "verify_onnx"])]
5871
verify_all: bool,
72+
/// Attention mode to use for memory reads.
5973
#[arg(
6074
long,
6175
default_value = "average-hard",
6276
value_parser = parse_attention_mode
6377
)]
6478
attention_mode: Attention2DMode,
6579
},
80+
/// Run the interactive terminal viewer for a program.
6681
Tui {
82+
/// Path to the source `.tvm` program.
6783
program: PathBuf,
84+
/// Maximum number of execution steps before stopping.
6885
#[arg(long, default_value_t = 512)]
6986
max_steps: usize,
87+
/// Number of transformer layers to distribute instructions across.
7088
#[arg(long, default_value_t = 1)]
7189
layers: usize,
90+
/// UI refresh interval in milliseconds.
7291
#[arg(long, default_value_t = 60)]
7392
tick_ms: u64,
93+
/// Attention mode to use for memory reads.
7494
#[arg(
7595
long,
7696
default_value = "average-hard",
7797
value_parser = parse_attention_mode
7898
)]
7999
attention_mode: Attention2DMode,
80100
},
101+
/// Export the compiled program as per-instruction ONNX graphs.
81102
ExportOnnx {
103+
/// Path to the source `.tvm` program.
82104
program: PathBuf,
105+
/// Directory where ONNX models and metadata will be written.
83106
#[arg(short = 'o', long = "output-dir")]
84107
output_dir: PathBuf,
108+
/// Number of transformer layers to distribute instructions across.
85109
#[arg(long, default_value_t = 1)]
86110
layers: usize,
111+
/// Attention mode to use for memory reads.
87112
#[arg(
88113
long,
89114
default_value = "average-hard",
90115
value_parser = parse_attention_mode
91116
)]
92117
attention_mode: Attention2DMode,
93118
},
119+
/// Produce a STARK proof for a supported execution.
94120
ProveStark {
121+
/// Path to the source `.tvm` program.
95122
program: PathBuf,
123+
/// File where the serialized proof JSON will be written.
96124
#[arg(short = 'o', long = "output")]
97125
output: PathBuf,
126+
/// Maximum number of execution steps before stopping.
98127
#[arg(long, default_value_t = 512)]
99128
max_steps: usize,
129+
/// Number of transformer layers to distribute instructions across.
100130
#[arg(long, default_value_t = 1)]
101131
layers: usize,
132+
/// Attention mode to use for memory reads.
102133
#[arg(
103134
long,
104135
default_value = "average-hard",
105136
value_parser = parse_attention_mode
106137
)]
107138
attention_mode: Attention2DMode,
108139
},
140+
/// Verify a previously generated STARK proof.
109141
VerifyStark {
142+
/// Path to the serialized proof JSON file.
110143
proof: PathBuf,
111144
},
112145
}
@@ -137,6 +170,20 @@ struct EngineRunOutput {
137170
events: Vec<ExecutionTraceEntry>,
138171
}
139172

173+
#[derive(Debug, Clone)]
174+
struct RunCommandOptions {
175+
program: PathBuf,
176+
max_steps: usize,
177+
trace: bool,
178+
layers: usize,
179+
engine: CliExecutionEngine,
180+
verify_native: bool,
181+
verify_burn: bool,
182+
verify_onnx: bool,
183+
verify_all: bool,
184+
attention_mode: Attention2DMode,
185+
}
186+
140187
#[cfg(feature = "onnx-export")]
141188
struct ScopedTempDir {
142189
path: PathBuf,
@@ -190,8 +237,8 @@ fn run() -> llm_provable_computer::Result<()> {
190237
verify_onnx,
191238
verify_all,
192239
attention_mode,
193-
} => run_program_command(
194-
&program,
240+
} => run_program_command(RunCommandOptions {
241+
program,
195242
max_steps,
196243
trace,
197244
layers,
@@ -201,7 +248,7 @@ fn run() -> llm_provable_computer::Result<()> {
201248
verify_onnx,
202249
verify_all,
203250
attention_mode,
204-
)?,
251+
})?,
205252
Command::Tui {
206253
program,
207254
max_steps,
@@ -231,25 +278,18 @@ fn run() -> llm_provable_computer::Result<()> {
231278
Ok(())
232279
}
233280

234-
fn run_program_command(
235-
program: &Path,
236-
max_steps: usize,
237-
trace: bool,
238-
layers: usize,
239-
engine: CliExecutionEngine,
240-
verify_native: bool,
241-
verify_burn: bool,
242-
verify_onnx: bool,
243-
verify_all: bool,
244-
attention_mode: Attention2DMode,
245-
) -> llm_provable_computer::Result<()> {
246-
let model = compile_model(program, layers, attention_mode.clone())?;
247-
let executed = execute_engine(&model, engine, max_steps)?;
281+
fn run_program_command(options: RunCommandOptions) -> llm_provable_computer::Result<()> {
282+
let model = compile_model(
283+
&options.program,
284+
options.layers,
285+
options.attention_mode.clone(),
286+
)?;
287+
let executed = execute_engine(&model, options.engine, options.max_steps)?;
248288

249-
print_execution_summary(program, engine, &model, &executed.result);
289+
print_execution_summary(&options.program, options.engine, &model, &executed.result);
250290

251-
if verify_native {
252-
let comparison = verify_model_against_native(model.clone(), max_steps)?;
291+
if options.verify_native {
292+
let comparison = verify_model_against_native(model.clone(), options.max_steps)?;
253293
println!("verified_against_native: true");
254294
println!("verified_steps: {}", comparison.checked_steps);
255295
println!(
@@ -262,8 +302,8 @@ fn run_program_command(
262302
);
263303
}
264304

265-
if verify_burn {
266-
let verification = verify_burn_engines(&model, max_steps)?;
305+
if options.verify_burn {
306+
let verification = verify_burn_engines(&model, options.max_steps)?;
267307
print_verification_summary(
268308
"verified_against_burn",
269309
"verified_burn",
@@ -272,8 +312,8 @@ fn run_program_command(
272312
);
273313
}
274314

275-
if verify_onnx {
276-
let verification = verify_onnx_engines(&model, max_steps)?;
315+
if options.verify_onnx {
316+
let verification = verify_onnx_engines(&model, options.max_steps)?;
277317
print_verification_summary(
278318
"verified_against_onnx",
279319
"verified_onnx",
@@ -282,8 +322,8 @@ fn run_program_command(
282322
);
283323
}
284324

285-
if verify_all {
286-
let verification = verify_all_engines(&model, max_steps)?;
325+
if options.verify_all {
326+
let verification = verify_all_engines(&model, options.max_steps)?;
287327
print_verification_summary(
288328
"verified_all",
289329
"verified_all",
@@ -292,7 +332,7 @@ fn run_program_command(
292332
);
293333
}
294334

295-
if trace {
335+
if options.trace {
296336
print_trace(&executed.trace, &executed.events);
297337
}
298338

src/burn_model.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -222,7 +222,7 @@ impl<B: Backend> BurnTransformerVm<B> {
222222
let mut banks = vec![vec![None; model.program().len()]; model.config().num_layers];
223223
let mut layer_for_pc = Vec::with_capacity(model.program().len());
224224

225-
for pc in 0..model.program().len() {
225+
for (pc, _) in model.program().instructions().iter().enumerate() {
226226
let (compiled, layer_idx) = model.compiled_instruction(pc as u8)?;
227227
layer_for_pc.push(layer_idx);
228228
banks[layer_idx][pc] = Some(BurnCompiledInstruction::from_compiled(compiled, device));

src/onnx_export.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,8 @@ fn export_instruction_onnx(
440440
model.domain = "com.llm_provable_computer".to_string();
441441
model.model_version = FORMAT_VERSION as i64;
442442
model.doc_string =
443-
"Per-instruction llm-provable-computer feed-forward export with explicit flag outputs".to_string();
443+
"Per-instruction llm-provable-computer feed-forward export with explicit flag outputs"
444+
.to_string();
444445
model.graph = MessageField::some(graph);
445446
model
446447
}

src/proof.rs

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -418,19 +418,20 @@ impl VmAir {
418418
}
419419
}
420420

421-
let mut constraints = Vec::new();
422-
constraints.push(valid_pc);
423-
constraints.push(valid_sp);
424-
constraints.push(current_zero.clone() * (current_zero.clone() - one.clone()));
425-
constraints.push(current[HALTED].clone());
426-
constraints.push(current[CARRY].clone());
427-
constraints.push(next_pc - expected_next_pc);
428-
constraints.push(next_acc.clone() - expected_next_acc);
429-
constraints.push(next_sp - expected_next_sp);
430-
constraints.push(next_halted - expected_next_halted);
431-
constraints.push(next_carry);
432-
constraints.push(next_acc.clone() * next_acc_inv - (one.clone() - next_zero.clone()));
433-
constraints.push(next_zero * next_acc);
421+
let mut constraints = vec![
422+
valid_pc,
423+
valid_sp,
424+
current_zero.clone() * (current_zero.clone() - one.clone()),
425+
current[HALTED].clone(),
426+
current[CARRY].clone(),
427+
next_pc - expected_next_pc,
428+
next_acc.clone() - expected_next_acc,
429+
next_sp - expected_next_sp,
430+
next_halted - expected_next_halted,
431+
next_carry,
432+
next_acc.clone() * next_acc_inv - (one.clone() - next_zero.clone()),
433+
next_zero * next_acc,
434+
];
434435

435436
if !self.layout.memory_size.is_zero() {
436437
constraints.push(

0 commit comments

Comments
 (0)