You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Decision: standardize on ordeal as loom's only solver and remove Z3. Recording it as an issue because it is an architecture change with consequences beyond the verifier, and because the evidence for doing it now has accumulated rather than been argued.
Why now — four independent pressures, not a preference
It is the wasip2 friction. Building loom for wasm32-wasip2 locally fails in z3-sys with could not find native static library c++`` — we carry a forked z3.rs branch for wasi-sdk support to get as far as we do. A pure-Rust solver removes the fork and the C++ sysroot problem together.
Tier-1 already proved the pattern.Adopt ordeal for certificate-checked optimization-rule verification (replace loom's own Z3 path) #277 moved the algebraic rule verifier behind a swappable backend: 38/38 rules proven, reported identically by both engines, and in both mode the harness runs both per obligation and panics on divergence — it did not. The migration seam, the differential harness and the answer to "do they agree" all exist already.
The last capability blocker is gone. ordeal#70 (symbolic-index array select/store) shipped in 0.11.0; loom is on 0.17.0. There is no longer a modelling gap that forces Z3 for the memory fragment.
Measured surface — smaller than the line count suggests
verify.rs is 9,696 lines, but the Z3 API surface across the whole crate is eight types in five files:
verify.rs use z3::ast::{Array, BV, Bool};
use z3::{Config, FuncDecl, SatResult, Solver, Sort, with_z3_config};
verify_rules.rs verify_e2e.rs islands.rs rule_solver.rs
Every one has a direct ordeal counterpart — BvTerm/BoolTerm, Solver/CheckResult, Sort, and sliver's array + uninterpreted-function support for Array/FuncDecl. The bulk of those 9.7k lines is term construction over BV/Bool, which is mechanical to port, not a redesign.
Run LOOM_VERIFY_BACKEND=both through the migration so every obligation is cross-checked against the incumbent while it is still present. Divergence is a hard failure, not a warning.
Drop the z3 dependency and the forked z3.rs only once both mode is clean across the full suite.
#300 asks for refinement-based validation with traps as first-class state, rather than value-equivalence plus guards. Do not port the current total-model encoding to ordeal and then re-architect it. Tier-2 and #300 are one piece of work: port and change the relation in the same pass, keeping the existing static guards as a floor throughout. Porting twice is the only way to make this expensive.
What it buys
No C++ toolchain in the build — Linux portability, musl, and wasip2 stop being three separate fights.
Certificates we can re-check: ordeal returns an LRAT proof for every Unsat and loom validates it before believing the verdict. That is evidence the incumbent never offered.
verify.rs is the safety-critical core; a silent regression here is the worst failure mode loom has. The both-mode differential is the mitigation and it must stay on for the whole migration, not just the start.
Performance is unmeasured at the core-validator scale. Tier-1 showed agreement, not throughput parity. If ordeal is materially slower on the big obligations, that is a finding to publish, not to hide.
Decision: standardize on ordeal as loom's only solver and remove Z3. Recording it as an issue because it is an architecture change with consequences beyond the verifier, and because the evidence for doing it now has accumulated rather than been argued.
Why now — four independent pressures, not a preference
GLIBCXX_3.4.31and would not load on ubuntu-22.04. That symbol requirement exists only because loom links Z3 (C++). v1.3.0 pins the builder image and asserts the floor, but that is a workaround for a dependency we intend to delete.wasm32-wasip2locally fails inz3-syswithcould not find native static libraryc++`` — we carry a forkedz3.rsbranch for wasi-sdk support to get as far as we do. A pure-Rust solver removes the fork and the C++ sysroot problem together.bothmode the harness runs both per obligation and panics on divergence — it did not. The migration seam, the differential harness and the answer to "do they agree" all exist already.Measured surface — smaller than the line count suggests
verify.rsis 9,696 lines, but the Z3 API surface across the whole crate is eight types in five files:Every one has a direct ordeal counterpart —
BvTerm/BoolTerm,Solver/CheckResult,Sort, andsliver's array + uninterpreted-function support forArray/FuncDecl. The bulk of those 9.7k lines is term construction overBV/Bool, which is mechanical to port, not a redesign.Plan
LOOM_VERIFY_BACKEND=boththrough the migration so every obligation is cross-checked against the incumbent while it is still present. Divergence is a hard failure, not a warning.z3dependency and the forkedz3.rsonly oncebothmode is clean across the full suite.Sequencing with #300 — this is the important one
#300 asks for refinement-based validation with traps as first-class state, rather than value-equivalence plus guards. Do not port the current total-model encoding to ordeal and then re-architect it. Tier-2 and #300 are one piece of work: port and change the relation in the same pass, keeping the existing static guards as a floor throughout. Porting twice is the only way to make this expensive.
What it buys
Unsatand loom validates it before believing the verdict. That is evidence the incumbent never offered.Honest risks
verify.rsis the safety-critical core; a silent regression here is the worst failure mode loom has. Theboth-mode differential is the mitigation and it must stay on for the whole migration, not just the start.Refs #277, #300, #311, #283, #246