Skip to content

feat(safety): rivet init, STPA analysis, and 5 code-verified gap fixes#61

Merged
avrabe merged 8 commits intomainfrom
feat/rivet-stpa-safety-analysis
Mar 22, 2026
Merged

feat(safety): rivet init, STPA analysis, and 5 code-verified gap fixes#61
avrabe merged 8 commits intomainfrom
feat/rivet-stpa-safety-analysis

Conversation

@avrabe
Copy link
Contributor

@avrabe avrabe commented Mar 22, 2026

Summary

  • Initialize rivet traceability (common + stpa + dev schemas) matching sister projects kiln, meld, synth
  • Full STPA safety analysis of LOOM's 12-phase optimization pipeline
  • Code-verified gap analysis with 6 parallel investigation agents
  • 5 confirmed gaps fixed, all tests passing

STPA Artifacts (185 total)

  • 6 losses, 20 hazards, 8 sub-hazards, 19 system constraints
  • 7 controllers, 3 controlled processes, 19 control actions
  • 25 UCAs, 24 controller constraints, 15 loss scenarios
  • 18 requirements, 7 design decisions, 14 features
  • Coverage: 98.9%, rivet validate PASS

Code-Verified Gap Fixes

Gap Fix Files
Z3 K-induction silently passes on UNKNOWN Return Ok(false) instead of assuming equivalent verify.rs
HashMap non-determinism in CSE + inlining HashMap -> BTreeMap for iteration-order-sensitive maps lib.rs, fused_optimizer.rs
Float fold NaN not canonicalized Canonical NaN enforcement + subnormal skip guard loom-shared/src/lib.rs
Z3 only tested on 1 fixture in CI Verify all .wat fixtures + .wasm files in verify job ci.yml
No binaryen comparison in CI New differential job: LOOM vs wasm-opt -O3 on all fixtures ci.yml

Mitigated (guards already exist)

  • CSE memory loads: is_safe_to_cse() rejects loads/stores/calls
  • DCE br_if: only Return/Unreachable set reachable=false
  • Inlining local remapping: proper offset + remap_locals_in_block()
  • Precompute mutable globals: if global.mutable { continue; }

Still open

  • H-17: Stack validation disabled (lib.rs:5732) — needs false positive investigation

Test plan

  • cargo test --release — all 32 loom-core tests pass
  • rivet validate — PASS (2 warnings, expected)
  • cargo build --release — clean build
  • CI workflows (Z3 verify, differential, self-optimization)

🤖 Generated with Claude Code

avrabe and others added 7 commits March 22, 2026 07:57
…irements

Add rivet traceability (common + stpa + dev schemas) matching sister
projects kiln, meld, synth. Full STPA covering the 12-phase optimization
pipeline: 6 losses, 16 hazards, 6 sub-hazards, 15 system constraints,
7 controllers, 25 UCAs, 24 controller constraints, 15 loss scenarios.
18 requirements migrated from CLAUDE.md, 7 design decisions from docs.
161 total artifacts, rivet validate PASS.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ysis

STPA findings verified against actual codebase:
- H-17: Stack validation DISABLED (lib.rs:5732-5750) - confirmed
- H-18: Z3 verification not in main CI test suite - confirmed
- H-19: Large unsupported instruction skip list on main - confirmed
- H-20: HashMap non-determinism in CSE - confirmed
- LS-6 (DCE br_if): MITIGATED - only Return/Unreachable are terminators
- LS-7 (CSE memory loads): MITIGATED - is_safe_to_cse rejects memory ops
- LS-12 (Z3 UNKNOWN): PARTIALLY CONFIRMED - main path rejects, loop path silent
- UCA-12 (inline remapping): MITIGATED - proper local offset + remap
- UCA-17 (precompute mutable): MITIGATED - global.mutable check exists

Added 14 features, 4 new hazards, 4 new system constraints.
183 total artifacts, 98.9% traceability coverage.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Agent-verified findings against actual codebase:
- LS-2 CONFIRMED: float folding uses host arithmetic, partial NaN guard
  only checks operands not results (loom-shared:3214-3404), no subnormal
  handling. Added H-1.4 (NaN result) and H-1.5 (subnormal flush).
- LS-3 NOT APPLICABLE: truncation ops in unsupported skip list
- LS-7 MITIGATED: no Load in Expr enum, stack cleared, is_pure() guard
- LS-12 PARTIALLY CONFIRMED: main path rejects UNKNOWN, loop K-induction
  silently passes (verify.rs:1063-1065), no Z3 timeout configured
- LS-15 CONFIRMED: 2 critical HashMap iterations affect output
  (lib.rs:9868 inlining, fused_optimizer.rs:899 adapter chains)

185 total artifacts, PASS with 2 warnings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…nism

1. Z3 K-induction: UNKNOWN and Err now return Ok(false) instead of
   silently assuming equivalence (verify.rs:1063, 1624, 1903)

2. HashMap non-determinism: Replace HashMap with BTreeMap in CSE
   pattern grouping, enhanced CSE hash tracking, function inlining
   candidate selection, and adapter chain resolution — ensures
   deterministic optimization output across runs

3. Float canonical NaN: Add WebAssembly canonical NaN enforcement
   (f32: 0x7fc00000, f64: 0x7ff8000000000000) when fold result is
   NaN. Add subnormal guard — skip folding when result is subnormal
   to avoid host FPU flush-to-zero divergence

4. Z3 CI coverage: Add fixture-wide Z3 verification to verify job
   (all .wat fixtures + .wasm test files, non-fatal per file)

5. Binaryen differential: Add CI job comparing LOOM vs wasm-opt -O3
   on all fixtures — fails if LOOM produces invalid WASM where
   wasm-opt succeeds

Addresses: H-17 partially (stack validation still disabled),
H-18, H-20, H-1.4, H-1.5, LS-12, LS-15, SC-17, SC-19

All 32 loom-core tests pass.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rust 1.94.0 (2026-03-02) generates thread-local storage initialization
that requires __wasi_init_tp, which is not available in the wasip2
component model with wasi-sdk-25. Disable atomics, bulk-memory, and
mutable-globals target features to avoid the linker error.

This is a pre-existing issue (Rust 1.94 released after last green CI
on March 1) exposed by this PR triggering CI.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@avrabe avrabe force-pushed the feat/rivet-stpa-safety-analysis branch from 3f87e71 to ae724ce Compare March 22, 2026 14:02
Rust 1.94.0 bundles a wasm-component-ld that generates __wasi_init_tp
imports which the wasip2 component model cannot resolve with wasi-sdk-25.
Pin to 1.93.1 (last known working, confirmed in CI run 22541892477 on
2026-03-01). 1.93.0 also fails — the fix was in 1.93.1 specifically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@avrabe avrabe force-pushed the feat/rivet-stpa-safety-analysis branch from ae724ce to c64224d Compare March 22, 2026 14:03
@avrabe avrabe merged commit db9aa0c into main Mar 22, 2026
21 checks passed
@avrabe avrabe deleted the feat/rivet-stpa-safety-analysis branch March 22, 2026 18:32
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