refactor(lfm,stark): delete the preprocessed round root and the mixed-height MMCS - #974
Merged
Merged
Conversation
…-height MMCS `prep_root` and `prep_widths` leave `LfmRegistryEntry` and `LfmArtifacts`, and the machinery behind them goes with them: `PREP_ROUND_SLOTS`, `prep_round_dims`, `pinned_prep_widths` (method and free function), `prep_round_shape`, `slot_of_table`, `commit.rs`'s `PrepRoundBuilder`, `stark::batched` (`shape.rs` and its `mod.rs`) and `stark::fri::mmcs`. They were one thing: a SECOND commitment over the preprocessed matrices the per-slot `roots` already commit individually, gathered into one mixed-height tree. The machine proves and verifies a per-table `MultiProof` whose openings authenticate against `roots`, so nothing read the round — `verify_against_ artifacts` said so in its own doc. With no reader, the round was a pinned constant that every `build_artifacts` call paid a tree for and six registry entries carried. `slot_of_table` goes because `pinned_prep_widths` was its only caller: it mapped an epoch TABLE index back to a registry SLOT across the chunking and chip-mask shifts, and that translation existed to index the round's width slice. `par::par_for_each_mut_indexed` goes for the same reason — its only caller was `fri/mmcs.rs:776`. No blessed value is hand-edited. The six entries lose two FIELDS; every root, `program_id` and height in them is byte-identical, and `lfm_program_id` never took the round as an argument, so no digest moves. `compute_lfm_registry` stops emitting the two fields, so a regenerated table matches the struct. Tests: the seven M-6 prep-round tests in `machine_tests.rs` and the twelve drift assertions that paired `entry.prep_root`/`prep_widths` against the artifacts, plus `blake3_chip_tests::the_prep_round_expands_with_the_blake3_ chunks`. `verify_against_artifacts_agrees_with_the_registry_path` sits inside the same banner and STAYS — it is M-7's honest-path control for a function that stays. `stark::batched::shape` carried no tests; `fri/mmcs.rs` carried fourteen, whose subject was the mixed-height tree itself.
This was referenced Sep 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Deletes the preprocessed round root and the mixed-height MMCS that built it. With
#973 merged there is one proof format on this branch; this removes the last structure
that existed only to serve the other one.
+16 / −3,151 over 13 files, one signed commit. Figures are
git diff --numstatagainst the merge base at this head, and the table sums to them.
crypto/starkbatched/{mod,shape}.rsandpub mod batched;,fri/mmcs.rsandpub mod mmcs;,par::par_for_each_mut_indexedprover/src/lfmprep_root/prep_widthsin both structs and their six entries,PREP_ROUND_SLOTS,prep_round_dims,prep_round_shape,pinned_prep_widths(method + free fn),slot_of_table,commit.rs'sPrepRoundBuilder, and the tests whose subject they areprover/src/bincompute_lfm_registrystops emitting the two fieldsWhy it goes
prep_rootwas a SECOND commitment over the preprocessed matrices the per-slotrootsalready commit individually, gathered into one mixed-height tree. The machine proves and
verifies a per-table
MultiProofwhose openings authenticate againstroots, so nothingread the round —
verify_against_artifactssaid exactly that in its own doc, under a"What it does NOT do yet" heading. With no reader, the round was a pinned constant that
every
build_artifactscall paid a tree for and that six registry entries carried.Two things die with it because they existed only to serve it, and both were verified by
reading callers rather than by name:
slot_of_tablemapped an epoch TABLE index back to a registry SLOT across thechunking and chip-mask shifts. Its only production caller was inside
pinned_prep_widths, where the translation existed to index the round's width slice.par::par_for_each_mut_indexedhad exactly one caller,fri/mmcs.rs:776.No blessed value is hand-edited
The six registry entries lose two FIELDS. Every root,
program_idand height in them isbyte-identical: the deletion cut whole
prep_root: [ … ],+prep_widths: [ … ],linegroups by matching structure, asserting exactly six matches, and touched no digit of any
value.
lfm_program_idnever took the round as an argument — the entry carried the pins,the digest did not — so no digest moves and this is not a re-bless.
compute_lfm_registryis updated in the SAME commit. It printedprep_root:andprep_widths:into the generated table, so left alone it would not have compiled, and hadit compiled it would have emitted a registry with fields the struct no longer has. That
matters beyond this PR: it is the step-8b regenerator, and a defect there surfaces during
the pin ceremony, which is the worst place in this campaign to find one.
Tests
Deleted: the seven M-6 prep-round tests in
machine_tests.rs, the twelve drift assertionsthat paired
entry.prep_root/prep_widthsagainst the artifacts (six identical pairs),blake3_chip_tests::the_prep_round_expands_with_the_blake3_chunks, andfri/mmcs.rs'sfourteen, whose subject is the mixed-height tree itself.
batched/shape.rscarried none.verify_against_artifacts_agrees_with_the_registry_pathSTAYS. It sat inside the same// The batched preprocessed round (M-6)banner, which ran to end of file, but it is M-7'shonest-path control for a function that stays. The banner is not the criterion — each
of the seven was confirmed by reading that it touches
prep_root/prep_round_*/pinned_prep_widths. The same check is whythe_slot_to_table_map_is_not_the_identity_beyond_one_chunkDOES go: it reads as asurvivor by name, and its subject dies with
pinned_prep_widths.Bycatch, not churn
Three comments in
registry.rs's build leg became false when the LDE stopped beingconsumed twice, and one of them said
commit_group"used to do its own expansion" —a migration reference with a shelf life of weeks. All three are rewritten in present tense
to describe what the code does now.
lde_columns' doc loses the same paragraph for thesame reason, along with an intra-doc link to
prep_round_root— a name that, checkedacross the whole tree, never named an item.
#973 also left two references to
a_batched_lfm_epoch_is_refused_for_the_round_coverage_gap,a test it had itself deleted; both sat inside text this PR removes.
Evidence
Laptop, at this head:
Box gate at this head, on a 32-core box, preconditions asserted before a test ran:
Predicted 1088 / 8 / 43 = 1139 before the run; measured 1088 / 8 / 43, with
--listindependently returning 1139. Stark was predicted at 271 / 0 / 3 = 274 and measured
there. math-cuda unchanged at 171 / 0, as predicted — this PR touches no math-cuda file.
The stark run's three ignored are doc-tests, which is why they survive a commit that
deletes fourteen unit tests:
crypto/stark/srccarries exactly three```ignorefencedblocks before and after, and none of the three deleted files carried one.
The eight failures are the RPX pin's, byte-identical to the set #973 gated and named; none
is in this PR's deletion set. That they are unchanged across a tree with
prep_root,prep_widths,PrepRoundBuilder,slot_of_tableand the mixed-height MMCS all removed isthe evidence that nothing read the preprocessed round back — compiling clean would only
have shown that nothing REFERENCES it.
Two independent derivations for the prover figure, both pre-registered:
exactly eight
#[test]s — seven M-6 plus one blake3_chip — all in plain#[cfg(test)]modules, none
#[ignore]d, and none among the eight known-red (the four redmachine_testsare the register-derivation trio andtranscript_replay_cell_counts,all outside the M-6 banner). 1096 − 8 = 1088.
prover/srccarries 1,161#[test]attributes against1,147 measured runnable — a gap of exactly 14, and it was 14 at the previous head too
(1,160 / 1,146), so it is stable. This commit takes attributes to 1,153 and removes
nothing from a gated module, so the gap holds: 1,153 − 14 = 1,139. The gate's own
--listreturned 1,139.One counting note, and one measurement note
An
#[test]ATTRIBUTE count is not a count of what RUNS, and it errs in BOTH directions.prover/srcover-counts (1,161 against 1,147 runnable —cfg-gated modules), whilecrypto/starkUNDER-counts: at the previous headsrc+testscarried 219 attributesagainst 288 measured runnable, in a crate where an earlier attribute-derived prediction of
307 missed that same 288. So the stark prediction above rested on ONE route — 285 passing at the previous head with
zero failures, minus fourteen non-ignored passing tests, giving 271 — and this PR does not
manufacture a second. The gate command instead runs
cargo test --release -p stark --lib -- --list, so the run carries its own count ratherthan a derived one. It returned 271, and the four
test result:lines sum to271 / 0 / 3 = 274 — the predicted figure exactly.
The same lines correct a stale description worth writing down: stark's suite is the lib
binary, TWO integration binaries and doc-tests, not the "lib plus three integration
binaries" an earlier characterisation recorded. Four result lines, three
Runningheaders— the fourth is doc-tests, which prints no
Running tests/…line — so anyonereconstructing the split from the older wording attributes the ignored three to the wrong
place.
★ The measurement note is worth more than the counting one. A previous gate on this lane
returned
900 passed; 204 failed; 43 ignored— it parsed cleanly, printed every expectedline, and every figure in it was meaningless: a fresh worktree had no guest ELFs, so every
suite that executes a guest program failed on a missing file. What caught it was a
prediction written down beforehand, and specifically that the total matched to the unit
while the split did not — 900 + 204 + 43 = 1,147 exactly. A real regression moves both.
Pre-registration is not ceremony here; it is the only instrument that distinguishes a
broken run from a broken branch.