Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/compliance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,10 @@ jobs:

- name: Generate compliance report
id: report
uses: pulseengine/rivet/.github/actions/compliance@v0.19.0
uses: pulseengine/rivet/.github/actions/compliance@v0.22.0
with:
theme: dark
rivet-version: v0.19.0
rivet-version: v0.22.0
include-data-formats: true
report-label: ${{ steps.tag.outputs.tag }}
archive: 'true'
Expand Down
6 changes: 6 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -777,6 +777,12 @@ GitHub REST API).
2. **CI must pass completely**: Wait for ALL CI jobs to succeed before merging
3. **Watch the full CI run**: Do not assume CI passes — verify it
4. **Mythos delta pass**: Run per `### Pre-Release Mythos delta pass` above. Zero `confirmed` findings, OR every `confirmed` finding maps to an `approved LS-N` in `safety/stpa/loss-scenarios.yaml` with a shipped fix
5. **Release-readiness query (rivet ≥ v0.22.0)**: readiness is a query, not an opinion. Scope this release's requirement artifacts with the first-class `release:` field (`rivet release move <ID> vX.Y.Z`), then gate on:
```bash
rivet release status vX.Y.Z # human burn-down; exits non-zero when not cuttable
rivet release status vX.Y.Z --format json # CI-consumable: {"cuttable": bool, "not_verified": [...]}
```
The release is **cuttable** only when every scoped artifact is `verified`/`accepted` (an artifact whose V is closed — verification passing at the right levels — moves `implemented`→`verified`). The `compliance.yml` rivet pin is also v0.22.0. (Historical per-release `vX.Y` *tags* on artifacts are "shipped-in" markers and stay; the `release:` field is the single forward scope `rivet release status` queries.)

#### Release Steps

Expand Down
105 changes: 105 additions & 0 deletions meld-core/tests/golden_e2e.rs
Original file line number Diff line number Diff line change
Expand Up @@ -412,3 +412,108 @@ fn tier_b_separate_inputs_internalise_link() {
fn ls_cp_6_separate_inputs_internalise_link() {
tier_b_separate_inputs_internalise_link();
}

// ---------------------------------------------------------------------------
// Tier C (#297): execution on kiln — the safety-critical MCU-target runtime,
// not just wasmtime. This is the "honest boundary" Tier A/B disclose.
// ---------------------------------------------------------------------------

/// Locate the `kilnd` binary: `MELD_KILND` override, else the conventional
/// sibling-repo debug build. `None` (→ skip) when unavailable, mirroring the
/// fixture-absent skips above.
fn kilnd_path() -> Option<std::path::PathBuf> {
if let Ok(p) = std::env::var("MELD_KILND") {
let p = std::path::PathBuf::from(p);
if p.exists() {
return Some(p);
}
}
let conv =
std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("../../kiln/target/debug/kilnd");
conv.exists().then_some(conv)
}

/// Run a `--component` wasm on `kilnd` and report whether kiln executed it
/// successfully. `None` when kilnd is unavailable (→ skip). `tag` only
/// disambiguates the temp file (no `Date`/rand in tests — the caller-supplied
/// tag is unique per fixture+role). Uses `std::process::Command` fully
/// qualified to avoid the `wasmtime_wasi::...::Command` import above.
fn run_on_kiln(wasm: &[u8], tag: &str) -> Option<bool> {
let kilnd = kilnd_path()?;
let tmp = std::env::temp_dir().join(format!("meld_tierc_{tag}.wasm"));
std::fs::write(&tmp, wasm).ok()?;
let out = std::process::Command::new(&kilnd)
.arg(&tmp)
.arg("--component")
.arg("--wasi")
.output()
.ok()?;
let _ = std::fs::remove_file(&tmp);
let combined = format!(
"{}{}",
String::from_utf8_lossy(&out.stdout),
String::from_utf8_lossy(&out.stderr)
);
// kilnd prints an explicit success/failure line; exit code alone is
// unreliable across its run modes.
Some(combined.contains("executed successfully") && !combined.contains("Execution failed"))
}

/// Tier C (#297): a meld-fused component must EXECUTE on kiln — the
/// safety-critical MCU-target runtime — not only under wasmtime (Tier A/B).
///
/// `#[ignore]`d: today kiln's component executor looks for a core-instance
/// `_start` and cannot run meld's multi-core-module `--component` wrap (the
/// stubs, fused, fixup and caller modules, with a deferred start); it fails
/// with "No core instance exports _start". Filed as kiln#364. wasmtime runs
/// the same artifact via `wasi:cli/run` (Tier A/B green), so meld's output is
/// spec-valid. Un-ignore when kiln#364 lands; it then pins the meld-to-kiln
/// behavioural seam green.
#[test]
#[ignore = "blocked on kiln#364: kilnd requires a core-instance _start; can't run meld's multi-core-module fused component"]
fn tier_c_fused_executes_on_kiln() {
if kilnd_path().is_none() {
eprintln!("skipping Tier C: kilnd not found (set MELD_KILND or build ../../kiln)");
return;
}
let mut ran = 0usize;
for &name in &[
"release-0.2.0/hello_c_cli",
"release-0.2.0/hello_rust",
"release-0.2.0/hello_cpp_cli",
] {
let Some(orig) = fixture_bytes(name) else {
continue;
};
let tag = name.replace('/', "_");
// Baseline: the unfused original must run on kiln, else a fused
// failure can't be attributed to fusion.
match run_on_kiln(&orig, &format!("{tag}_orig")) {
Some(true) => {}
Some(false) => {
eprintln!("[{name}] unfused original did not execute on kiln; skipping");
continue;
}
None => return, // kilnd vanished mid-run
}
let fused = fuse(
&orig,
name,
OutputFormat::Component,
MemoryStrategy::MultiMemory,
)
.expect("fusing a single command component must succeed");
let ok = run_on_kiln(&fused, &format!("{tag}_fused")).expect("kilnd available (checked)");
assert!(
ok,
"[{name}] meld-fused component must execute on kiln (kiln#364): \
the unfused original ran but the fused one did not"
);
ran += 1;
}
assert!(
ran > 0,
"Tier C exercised no command fixtures (corpus missing in {FIXTURES_DIR}?)"
);
eprintln!("Tier C: {ran} fused components executed on kiln ✓");
}
3 changes: 2 additions & 1 deletion safety/requirements/safety-requirements.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1523,7 +1523,7 @@ artifacts:
(scry#63); meld is the producer, scry-provenance owns the format (DD-002).
meld shall NOT compute value ranges / constant args / dead params — those
are scry's abstract interpretation, fed by these premises (#313).
status: implemented
status: verified
tags: [feature, provenance, specialization, v0.37.0]
links:
- type: derives-from
Expand All @@ -1535,6 +1535,7 @@ artifacts:
- uri: "https://github.com/pulseengine/scry/issues/63"
kind: github
last-checked: 2026-06-26
release: v0.37.0
fields:
implementation:
- meld-core/src/provenance.rs
Expand Down
Loading