Skip to content

L7: traceability repair — rivet ours-errors 2 → 0, VCR-RA-004/SEL-005 de-staled, VCR-VER-004 filed (#893) #1144

L7: traceability repair — rivet ours-errors 2 → 0, VCR-RA-004/SEL-005 de-staled, VCR-VER-004 filed (#893)

L7: traceability repair — rivet ours-errors 2 → 0, VCR-RA-004/SEL-005 de-staled, VCR-VER-004 filed (#893) #1144

Workflow file for this run

# Fuzz smoke — short cargo-fuzz run (~60s / target) on every PR + push to main.
#
# Catches new panics / unencodable instructions / silent op drops in the
# WASM → IR → ARM lowering pipeline. Long-budget runs (1h / target with
# corpus persistence) are out of scope for #82; this is the smoke gate.
#
# Target list mirrors fuzz/Cargo.toml `[[bin]]` entries. Add a new
# fuzz_target there → add the binary name to `matrix.target` here.
#
# Refs: issue #82, issue #93 (silent-drop class).
name: Fuzz Smoke
on:
push:
branches: [main]
paths:
- 'crates/**'
- 'fuzz/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/fuzz-smoke.yml'
pull_request:
branches: [main]
paths:
- 'crates/**'
- 'fuzz/**'
- 'Cargo.toml'
- 'Cargo.lock'
- '.github/workflows/fuzz-smoke.yml'
permissions:
contents: read
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.ref }}
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
jobs:
fuzz:
name: "${{ matrix.target }} (60s)"
# Match ci.yml: rust-cpu self-hosted pool, with ubuntu-latest fallback if
# the pool is unavailable (cargo-fuzz needs Linux for libfuzzer-sys ASan).
runs-on: [self-hosted, linux, x64, rust-cpu]
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
# Each entry: `target` + `gating`. Gating harnesses pass clean today
# and block PR merge on regression. Exploration harnesses keep finding
# new bugs at a rate faster than we close them in one cycle; they
# report (crash artifacts uploaded) but don't block — `continue-on-
# error` is taken from the `gating` flag. Promote an exploration
# harness to gating once its bug-list stabilises.
include:
# `wasm_ops_lower_or_error` is gating again. It was demoted in
# PR #117 because wasm_to_ir's inst_id-as-vreg-slot model crashed
# on Drop / LocalSet / Store / Block shapes; the slot_stack
# refactor (issue #121) closed those. The last panic site in the
# optimized path was `ir_to_arm`'s defensive `get_arm_reg`, which
# now returns `Result` instead of `panic!`-ing — the whole
# `optimize_full` + `ir_to_arm` path is panic-free, so this
# harness (contract: "lower or Err, never panic") gates again.
- target: wasm_ops_lower_or_error
gating: true
- target: wasm_to_ir_roundtrip_op_coverage
gating: true
- target: i64_lowering_doesnt_clobber_params
gating: false # finds real bugs faster than we fix them; tracked as follow-up issues
- target: encoder_no_panic
gating: false # encoder-level corner cases; not silicon-blocking
# When gating == false, treat job failure as a non-blocking warning. The
# matrix value is plain JSON (bool), not untrusted user input, so this is
# safe to interpolate.
continue-on-error: ${{ matrix.gating == false }}
steps:
- uses: actions/checkout@v7
- name: Install nightly Rust
uses: dtolnay/rust-toolchain@nightly
- uses: actions/cache@v6
with:
path: |
~/.cargo/registry
~/.cargo/git
fuzz/target
key: fuzz-${{ runner.os }}-${{ hashFiles('Cargo.lock', 'fuzz/Cargo.toml') }}
restore-keys: fuzz-${{ runner.os }}-
- name: Install cargo-fuzz
uses: taiki-e/install-action@v2.85.5
with:
tool: cargo-fuzz
- name: Run fuzz target for 60s
env:
TARGET: ${{ matrix.target }}
# Force the GNU target — cargo-fuzz defaults to musl on Linux,
# whose statically-linked libc is incompatible with ASan
# (libfuzzer-sys turns ASan on by default). The GNU target has
# a dynamic libc and works correctly.
#
# We seed the corpus from `fuzz/seed_corpus/<target>/` (checked into
# git) so known-crash inputs are always replayed — see PR #117 which
# introduced `seed_corpus/wasm_ops_lower_or_error/seed-pr117-i32divs-
# empty-stack`. Without seeding, a regression that re-introduces the
# panic might be missed if libfuzzer doesn't rediscover the exact
# input within 60s.
run: |
mkdir -p fuzz/artifacts fuzz/corpus "fuzz/corpus/${TARGET}"
if [ -d "fuzz/seed_corpus/${TARGET}" ]; then
cp -n fuzz/seed_corpus/"${TARGET}"/* "fuzz/corpus/${TARGET}/" || true
fi
cargo +nightly fuzz run "${TARGET}" \
--target x86_64-unknown-linux-gnu \
-- -max_total_time=60 -print_final_stats=1
- name: Upload crash artifacts
if: failure()
uses: actions/upload-artifact@v7
with:
name: fuzz-crash-${{ matrix.target }}
path: |
fuzz/artifacts/${{ matrix.target }}/
fuzz/corpus/${{ matrix.target }}/
retention-days: 30
if-no-files-found: ignore