Skip to content

FEAT-048 (v3.0): mechanized i32.add soundness vs official wrapping semantics (REQ-002, G-005)#87

Merged
avrabe merged 2 commits into
mainfrom
feat-048-wrapcert
Jul 1, 2026
Merged

FEAT-048 (v3.0): mechanized i32.add soundness vs official wrapping semantics (REQ-002, G-005)#87
avrabe merged 2 commits into
mainfrom
feat-048-wrapcert

Conversation

@avrabe

@avrabe avrabe commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

The differentiator — make REQ-002's "proven vs the official Wasm semantics"
literally true for the i32.add transfer, including the WRAP case.

The gap it closes

Soundness.v proved scry's interval add sound over unbounded ℤ (the no-wrap
sub-range, ⊤ otherwise). That never established soundness against the official
i32.add — two's-complement wraparound mod 2³².

proofs/rocq/WrapAdd.v (admit-free)

Models the official wrapping semantics directly —
wrap z = (z + 2³¹) mod 2³² − 2³¹, the same function WasmCert-Coq (TE-004)
mechanizes — and proves scry's shipped i32_add branch logic sound against
it, including the wrap case:

  • straddles mirrors the shipped lo < i32::MIN || hi > i32::MAX widen-to-⊤ test;
  • in-range ⟹ the real sum stays in i32, so wrap(x+y) = x+y (wrap_id) ∈ the
    exact interval;
  • widen ⟹ ⊤ = all i32 ∋ wrap(x+y) (wrap_in_i32).

Honesty (assessor-facing)

The file header is explicit: this mechanizes the same mathematical semantics
the spec mandates (and WasmCert-Coq formalizes), rather than importing the
WasmCert-Coq development (a literal dependency is deferred/DD-noted). No
overclaim of a WasmCert-Coq import scry doesn't have.

The false Verus join proof

Already repaired: proofs/verus/join_proofs.rs is the semantic γ-equality
statement (γ(join(a,b)) == γ(join(b,a)), true across all bottom-encodings where
structural == was false), and the Verus Formal Proofs CI job verifies it —
satisfying the other half of the AC.

Falsification statement

scry claims its i32_add result contains the official wrapping i32.add of any
operand-interval values, on every input. FALSE if WrapAdd.v's
i32_add_wrap_sound does not hold (it is machine-checked, admit-free).

rivet validate PASS. The Rocq Formal Proofs CI job is the authoritative check
for WrapAdd.v (local bare coqc lacks the Stdlib path the Bazel rocq
toolchain wires; Pentagon.v/Float.v use identical imports and are CI-green).

🤖 Generated with Claude Code

…mantics (REQ-002, G-005)

Closes the stated-but-unproven REQ-002 gap: Soundness.v proved scry's interval
add sound over UNBOUNDED Z (the no-wrap core, ⊤ otherwise), but not against the
OFFICIAL Wasm i32.add — two's-complement wraparound mod 2^32.

proofs/rocq/WrapAdd.v models the official wrapping semantics directly
(`wrap z = (z + 2^31) mod 2^32 - 2^31` — the same function WasmCert-Coq (TE-004)
mechanizes; a literal WasmCert-Coq import is deferred, honestly scoped in the
file header) and proves scry's SHIPPED i32_add branch logic sound against it,
INCLUDING the wrap case:
- `straddles` mirrors the shipped `lo < i32::MIN || hi > i32::MAX` widen-to-⊤ test;
- in-range branch: the real sum stays in i32, so `wrap(x+y) = x+y` (wrap_id via
  Z.mod_small) ∈ the exact interval;
- widen branch: ⊤ = all i32 ∋ `wrap(x+y)` (wrap_in_i32 via Z.mod_pos_bound).
Admit-free, no axioms.

The recorded-false Verus join proof (join_proofs.rs) is already REPAIRED to the
semantic γ-equality statement (`γ(join(a,b)) == γ(join(b,a))`, true across all
bottom-encodings where structural == was false) and the Verus CI job verifies
it — satisfying the other half of the AC.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 1, 2026

Copy link
Copy Markdown

📐 rivet artifact delta

PR: #87 Base SHA: 6b8b44e8

Validation

head — `rivet validate` result
  SR-11 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-12 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-13 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-2 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-3 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-4 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-5 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-6 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-7 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-8 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-9 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SYS-1 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-2 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-3 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-4 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-5 (system-req, status: accepted) — missing: sys-integration-verification
  → run `rivet validate --explain SR-1` to see which link type and source types satisfy a gap

Result: PASS (80 warnings)
Schemas: common@0.3.0 (embedded), dev@0.2.0 (embedded), research@0.1.0 (embedded), research-ext@0.1.0 (on-disk), safety-case@0.1.0 (embedded), aspice@0.2.0 (embedded)
base — `rivet validate` result (for comparison)
  SR-11 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-12 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-13 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-2 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-3 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-4 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-5 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-6 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-7 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-8 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SR-9 (sw-req, status: accepted) — missing: sw-integration-verification, unit-verification
  SYS-1 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-2 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-3 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-4 (system-req, status: accepted) — missing: sys-integration-verification
  SYS-5 (system-req, status: accepted) — missing: sys-integration-verification
  → run `rivet validate --explain SR-1` to see which link type and source types satisfy a gap

Result: PASS (80 warnings)
Schemas: common@0.3.0 (embedded), dev@0.2.0 (embedded), research@0.1.0 (embedded), research-ext@0.1.0 (on-disk), safety-case@0.1.0 (embedded), aspice@0.2.0 (embedded)

Artifact stats

base head
Total artifacts 203 203
full stats — head
Artifact summary:
  academic-reference               24
  competitive-analysis             11
  design-decision                  17
  feature                          58
  market-finding                    7
  requirement                      17
  safety-context                    3
  safety-goal                       5
  safety-justification              3
  safety-solution                   6
  safety-strategy                   1
  stakeholder-req                   3
  sw-req                           13
  sw-verification                  13
  sys-verification                  5
  system-req                        5
  technology-evaluation            12
  TOTAL                           203

Orphan artifacts (no links): 11
  CA-001
  CA-002
  CA-003
  CA-004
  CA-005
  CA-006
  CA-007
  CA-008
  CA-009
  CA-010
  CA-011

Diagnostics: 0 error(s), 80 warning(s), 16 info(s)

Diff (base → head)

~ FEAT-048
  status: - proposed -> + accepted

0 added, 0 removed, 1 modified, 202 unchanged

AADL model — head

spar/scry.aadl: OK

Posted by the rivet-delta workflow. Informational only — does not gate the PR.

Rocq CI: Z.mod_pos_bound wants '0 < W' but W_pos stated 'W > 0' (not
definitionally unified in Rocq 9.0). Also switch the orb-false case analysis to
the robust orb_false_iff lemma (with an explicit Bool require) instead of
destruct+simpl, which cannot reduce 'orb var true'.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@avrabe avrabe merged commit a074ca5 into main Jul 1, 2026
12 checks passed
@avrabe avrabe deleted the feat-048-wrapcert branch July 1, 2026 05:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant