fix(fpga): compute theorem_matrix_ok instead of hardcoding it true - #2343
Merged
Conversation
`let theorem_matrix_ok = true;` at cli/tri/src/fpga.rs:6101 was a verdict conjunct that no code path could ever set to false, ANDed into `passed` at :6342. So `tri fpga smoke-gate --theorem-matrix` certified 24 variants it never generated: `report["theorem_matrix"]` kept the null from its initializer while `passed` read true and the process exited 0. This is the compute-it case, not the no-such-check case. The phase's functions survived the merge that dropped its call site, and rustc had been reporting generate_theorem_matrix, replay_theorem_matrix, build_theorem_matrix_report and the two properties they check -- pvt_context_inside_envelope and cclk_period_ns -- as never used on every build. The 24-variant block they emit is still on disk in tests/fixtures/fpga/smoke-gate/validate_lean_standalone_snapshot.json. Restored in the shape verify_lean_ok uses twenty lines above: set the flag and write the report entry inside the success path, record the phase as failed and bail otherwise. --replay-fixtures and --dry-run-live were unused parameters, so --replay-fixtures had been silently regenerating instead of replaying; both are now wired to replay_theorem_matrix and to the documented dry_run_live label and theorem-matrix-dry-run-live/ directory. Two guards, two separate mutants, because assertions abort in order. Mutant A flips the PVT envelope bound to > PVT_TEMP_MAX_C: on master the gate still printed "[smoke-gate] complete (passed: true)" with "theorem_matrix": null and exit 0; after the fix it exits 1 with "theorem-matrix generation failed: theorem-matrix envelope-check failed for corner ff OSCFSEL 0: synthetic PVT context is outside the operating envelope". Mutant B walks two corners instead of three, leaving every generated variant valid so it cannot trip guard A: master again exits 0 with passed: true, and after the fix "theorem-matrix verified 16 variants, expected 24". test_smoke_gate_json_synthetic_verify_lean already passed run_theorem_matrix = true and asserted passed == true, which is precisely the assertion the hardcoded flag satisfied for free. The new test reads the theorem_matrix phase itself and opens each variant's .lean off disk, because a report block alone is satisfiable by a JSON literal. smoke_gate() derives its dry-run and fixture directories from the repo root rather than from arguments and clears stale logs there on entry, so a second concurrent test made it fail on a missing boot-log file. The four smoke-gate tests now take a mutex. No existing assertion was relaxed. Refs #2306 Item 2 of #2306, validate_lean_standalone_ok, is deliberately not fixed here: it fails closed rather than open, and both of its tests return early without `lake` on PATH, which is available neither on this machine nor on the cli-tri runner. Landing a phase body that cannot be executed once is how an unproven guard gets in. #2306 stays open on that item. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
August 21, 2026 15:58
Contributor
PR DashboardGenerated at: 2026-08-21 15:59:56 UTC
Summary
Seal Status
|
Contributor
|
📓 NotebookLM Notebook linked to this PR
This notebook contains session context, decisions, and artifacts for this work. |
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.
Refs #2306 (item 1 of two; see "Scope" at the bottom for why this is
Refsand notCloses).The defect is live on
origin/masterRe-verified on
ee494b990immediately before pushing —cli/tri/src/fpga.rs:6101:consumed at
:6342as the conjunctThose were its only two mentions. There was no theorem-matrix phase body in
smoke_gate(), so--theorem-matrixreported the phase passed without executing a line of it,report["theorem_matrix"]kept thenullfrom its initializer at:5970, and the process exited 0.This fails open, unlike its sibling
dry_run_sweep_ok(#2304, fixed in #2305), which was declaredfalseand never assigned and so failed closed — unpassable and loud.Which case this is: compute it
The underlying check does exist; only its call site was gone. rustc had been saying so on every build:
and the 24-variant block those functions emit is still committed in
tests/fixtures/fpga/smoke-gate/validate_lean_standalone_snapshot.json. So the honest fix is to compute the flag, not to delete it and not to leave a plausible-lookingtrue.The change
let mut theorem_matrix_ok = false;plus the restored phase, in the same shapeverify_lean_okuses twenty lines above: set the flag and write the report entry inside the success path, record the phase as failed andbail!otherwise.--replay-fixturesand--dry-run-livewere unused parameters —--replay-fixtureshad been silently regenerating instead of replaying — and are now wired toreplay_theorem_matrixand to the documenteddry_run_livelabel andtheorem-matrix-dry-run-live/directory.The three bars
TRUE
cargo test -p tri— 168 passed; 0 failed.cli/tri/src/fpga.rsisrustfmt-clean (the other 12 files in the crate have pre-existingcargo fmt --checkdiffs on master; none is touched here).ALIVE
The phase does real work: 24
.leanfiles on disk, 2 theorem declarations each, every one run throughverify_lean.The new test opens each variant's
.leanoff disk rather than trusting the JSON block, because a report object alone is satisfiable by a literal.BITING — two guards, two separate mutants
One mutant per guard, not one per file: assertions abort in order, and mutant B is chosen so that every variant it produces is valid, which means it cannot trip guard A and therefore proves guard B on its own.
Mutant A — sabotage the underlying property.
pvt_context_inside_envelopebound flipped,ctx.temp_c >= PVT_TEMP_MIN_C→ctx.temp_c > PVT_TEMP_MAX_C, so the envelope check is false for every context.Before (master, mutant planted) — the verdict still reports OK:
After (this branch, same mutant) — it bites:
and through the test:
Mutant B — cut the matrix short.
for corner_str in ["ff", "tt", "ss"]→["ff", "tt"]ingenerate_theorem_matrixonly (the identical line inreplay_theorem_matrixleft alone). All 16 variants it emits verify cleanly, so guard A stays silent.Before (master, mutant planted):
After (this branch, same mutant):
Reverted, both mutants removed:
Why the existing suite was blind to it
test_smoke_gate_json_synthetic_verify_leanalready passesrun_theorem_matrix = trueand assertspassed == true. That is exactly the assertion a hardcodedtruesatisfies for free, which is why a test that runs in CI today could never have caught this. The new test reads thetheorem_matrixphase itself, checks all 24 corner/OSCFSEL pairs appear exactly once, and opens the generated theorems.Nothing weakened
No
|| true, nocontinue-on-error, no relaxed assertion, no dropped case. One addition that is not the defect:smoke_gate()derives its dry-run and fixture directories from the repo root rather than from arguments and clears stale logs there on entry, so a second concurrent smoke-gate test made it die onremove ... boot-log-*.json: No such file or directory. Only one test reached those directories before, so the race had nothing to collide with. The four smoke-gate tests now take a mutex — serialisation only, no assertion touched.Cargo.lockis deliberately not in this PR: localcargoruns pruned 20 lines from it, which is a build artifact of my machine and not part of this change.Scope — why
Refs #2306and notCloses#2306 reports two defects and its own "Suggested order" puts this one first as "a live false-green today". Item 2,
validate_lean_standalone_ok, is deliberately not fixed here:lakeon PATH, which is on neither this machine nor thecli-trirunner, so I could not execute a candidate implementation even once.Landing a phase body that cannot be run, behind a proof gate, is how an unproven guard gets in. #2306 stays open on item 2, which is what
Refsrecords. Its own text already documents that item fully, so no duplicate issue is filed.Corpus Ratchet,Seal CoverageandFPGA E2E Buildare red on master already and are not required contexts.