Skip to content

feat(compose-witness): Wasm-component PoC for REQ-086 witness MC/DC#315

Merged
avrabe merged 1 commit into
mainfrom
feat/req-086-compose-witness
May 23, 2026
Merged

feat(compose-witness): Wasm-component PoC for REQ-086 witness MC/DC#315
avrabe merged 1 commit into
mainfrom
feat/req-086-compose-witness

Conversation

@avrabe
Copy link
Copy Markdown
Contributor

@avrabe avrabe commented May 23, 2026

Summary

First increment of REQ-086 (MC/DC coverage of the REQ-083 composition core via the pulseengine witness tool). The cargo-component side is fully working; the canonical Bazel pipeline via rules_wasm_component is sketched and pending live build verification.

What works

New sibling cargo project compose-witness/ (deliberately NOT a workspace member — keeps cargo test --all clean of wasm-only crate-types). Building it:

cargo component build --manifest-path compose-witness/Cargo.toml

…produces a valid Wasm component at compose-witness/target/wasm32-wasip1/debug/compose_witness.wasm. wasm-tools validate is clean; wasm-tools component wit confirms it exports exactly the WIT interface declared:

package pulseengine:compose-witness@0.1.0;
interface compose {
    prefix-features: func(model-yaml: string, prefix: string)
                      -> result<string, string>;
}
world compose-witness { export compose; }

The pure prefixing functions (prefix_model_yaml, prefix_constraint, flush_constraint_token — the constraint-tokenization gap llvm-cov surfaced under REQ-083) are inlined from rivet-core/src/feature_model.rs. rivet-core itself uses std::fs / salsa / rowan and would not compile to wasm32 as-is; v1 inlines, v2 extracts the pure module into a shared crate both depend on.

What's sketched (Bazel + witness)

  • bazel_dep(name = "rules_wasm_component", version = "1.0.0") added to MODULE.bazel.
  • compose-witness/BUILD.bazel wires wit_library + rust_wasm_component_bindgen + the wasm_module_coverage (witness) target, following the examples/witness_example pattern from rules_wasm_component (witness operates on core modules; single-component subjects go straight to coverage).

Bazel side is pending live build verification — that's the next increment (and the right place to iterate, since Bazel + rules_wasm_component + the witness toolchain is fastest to debug in-tree).

Why exclude from the cargo workspace?

The crate-type is cdylib targeting wasm32-wasip1. Including it as a workspace member would break cargo test --all and cargo clippy --workspace on the host (wit-bindgen-rt's export! macro generates wasm-specific bindings). Excluding it keeps the host workspace clean while still letting cargo component build --manifest-path work locally; Bazel doesn't care about cargo workspaces.

Test plan

  • cargo component build produces a valid component (verified locally — 8.0M debug Wasm, wasm-tools validate clean).
  • cargo check -p rivet-core from the workspace root does not pull in compose-witness (exclude works).
  • CI green (this PR adds no test surface to host CI — it's a sibling project; CI integration of the wasm/witness build is a follow-on increment).
  • Bazel bazel build //compose-witness:compose_witness_coverage (deferred to next increment).

🤖 Generated with Claude Code

First increment of REQ-086 (MC/DC coverage of the REQ-083 composition
core via the pulseengine `witness` tool). The cargo-component side is
fully working; the canonical Bazel pipeline via rules_wasm_component is
sketched in BUILD.bazel and pending live build verification.

New sibling cargo project `compose-witness/` (NOT a workspace member,
to keep `cargo test --all` clean of wasm-only crate-types). It builds
to a Wasm component (`cargo component build --manifest-path
compose-witness/Cargo.toml`) at
`compose-witness/target/wasm32-wasip1/debug/compose_witness.wasm`,
validates clean, and exports exactly the WIT interface declared:
`pulseengine:compose-witness/compose@0.1.0` with a single
`prefix-features(model-yaml, prefix) -> result<string, string>` export.

The pure prefixing functions (`prefix_model_yaml`, `prefix_constraint`,
`flush_constraint_token`) are inlined from
rivet-core/src/feature_model.rs — rivet-core itself uses
std::fs/salsa/rowan and would not compile to wasm32 as-is. A v2
increment extracts the pure module into a shared crate both depend on;
v1 deliberately duplicates so the wasm surface witness needs to
measure is the absolute minimum.

Bazel side: adds `bazel_dep(name = "rules_wasm_component", version =
"1.0.0")` to MODULE.bazel and sketches `compose-witness/BUILD.bazel`
with `wit_library` + `rust_wasm_component_bindgen` + the
`wasm_module_coverage` (witness) target. The Bazel build is pending
live verification — that's the next increment.

Implements: REQ-086
Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Rivet Criterion Benchmarks'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: ac3ab17 Previous: f88b23a Ratio
store_insert/10000 19957681 ns/iter (± 2082003) 14832494 ns/iter (± 1393194) 1.35

This comment was automatically generated by workflow using github-action-benchmark.

@codecov
Copy link
Copy Markdown

codecov Bot commented May 23, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@avrabe avrabe merged commit 78f001e into main May 23, 2026
20 of 39 checks passed
@avrabe avrabe deleted the feat/req-086-compose-witness branch May 23, 2026 13:31
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