v2.7.0
Headline: "Prove safety" — scry's first runtime-error verdicts. The
Astrée/Polyspace-style PROVEN-SAFE vs POTENTIAL-TRAP judgement scry entirely
lacked (MF-006), built on a new cheap relational domain. Three features
(FEAT-044/045/046).
Added — FEAT-044 (REQ-014, AC-014) — Pentagons domain
- New zero-dep
#![no_std]cratescry-sai-pentagon(Logozzo–Fähndrich):
per-variable intervals + a strict-less-than matrix, with the
interval-recovering join. The cheap relational layer (index < length)
behind OOB detection. Admit-free Rocq (proofs/rocq/Pentagon.v) for the join,
order, andclosederivations; exhaustive γ-sweep tests. close()returns canonical ⊥ on a strict cycle (self-loop after transitive
closure) before interval tightening — without that guard a cycle drives the
bounds toward the ±∞ sentinels ~2⁶³ steps (found by the soundness gate).- Analyzer pass
compute_pentagon_factsrecords thex < boundguards from
local.get i; (local.get j | const); lt_u/lt_s; if, library-only on
AnalysisResult.pentagon_facts.
Added — FEAT-045 (REQ-014, MF-006) — division/overflow trap detection
- Every
i32/i64.div_s/div_u/rem_s/rem_ureached by the interval interpreter
gets aDivByZeroverdict; everydiv_sadditionally aSignedOverflow
verdict.ProvenSafeonly when the divisor interval excludes0(resp. the
dividend excludesINT_MINOR the divisor excludes-1); else
PotentialTrap. Surfaced onAnalysisResult.trap_checks. - Modelling div/rem in the interpreter (was the unsupported-op fallback) stops
a division from degrading the whole function to ⊤. - SOUNDNESS (clean-room): per-pass verdicts are reconciled per
(func, pc, kind)
withPotentialTrapdominatingProvenSafe— a div in a loop body no longer
keeps a staleProvenSafefrom a pre-widening iterate.
Added — FEAT-046 (REQ-014, MF-006) — out-of-bounds memory trap detection
- Every load/store gets an
OutOfBoundsverdict.ProvenSafeonly when the
effective address (operand interval +memarg.offset) provably fits:
addr ≥ 0andaddr_hi + width ≤ size_bytes, wheresize_bytesis the
memory's GUARANTEED size (initial pages × 64 KiB) — a sound floor since memory
only grows. Reuses the FEAT-045 reconciliation. - The 4 modelled ops (
i32/i64.load/store) get precise verdicts; every other
load/store (narrow / float / degraded-state) getsPotentialTrap— never
silently dropped.
Posture
- All three are library-only
AnalysisResultfields (pentagon_facts,
trap_checks); thescry.witinterface and the frozen v1 invariant-JSON
contract are unchanged. scry-viz gained relational-guard + trap-check panels. - Trap verdicts only ever move toward conservatism (
ProvenSafeonly when
proven); precision over-approximations (loop-widened divisors/addresses,
imported/growable memory, narrow/float widths) are soundPotentialTraps. - Falsification statement. scry claims a
ProvenSafediv/rem never traps on
div-by-zero (resp.INT_MIN/-1), and aProvenSafeload/store never accesses
out of bounds, on any concrete run. FALSE if any.wathas aProvenSafe
operator that traps at runtime. Each feature was driven through an adversarial
clean-room (FEAT-044 found aclosenon-termination; FEAT-045 found a
loop-carried staleProvenSafe; both fixed with regressions before merge).