cellos-supervisor 0.5.1

CellOS execution-cell runner — boots cells in Firecracker microVMs or gVisor, enforces narrow typed authority, emits signed CloudEvents.
Documentation
//! L2-03 direction: two sequential supervisor processes share one export root; each cell id gets an isolated subdir.
//!
//! This does not prove kernel namespaces — only that the **export sink** layout does not merge runs.
//! For Linux **ipc/mnt** namespace identity across sequential runs, see `supervisor_linux_cross_run_ns.rs`.

#[cfg(unix)]
mod unix {
    use std::fs::File;
    use std::io::Write;
    use std::path::{Path, PathBuf};
    use std::process::Command;

    fn supervisor_exe() -> PathBuf {
        if let Some(p) = std::env::var_os("CARGO_BIN_EXE_cellos_supervisor") {
            return PathBuf::from(p);
        }
        let root = Path::new(env!("CARGO_MANIFEST_DIR"))
            .parent()
            .and_then(|p| p.parent())
            .expect("cellos-supervisor crate under workspace root");
        let profile = std::env::var("PROFILE").unwrap_or_else(|_| "debug".into());
        root.join("target").join(profile).join("cellos-supervisor")
    }

    fn write_spec(path: &Path, cell_id: &str, artifact_name: &str, src: &Path) {
        let spec = serde_json::json!({
            "apiVersion": "cellos.io/v1",
            "kind": "ExecutionCell",
            "spec": {
                "id": cell_id,
                "authority": { "secretRefs": [] },
                "lifetime": { "ttlSeconds": 60 },
                "export": {
                    "artifacts": [
                        { "name": artifact_name, "path": src.to_str().unwrap() }
                    ]
                }
            }
        });
        std::fs::write(path, serde_json::to_string(&spec).unwrap()).unwrap();
    }

    #[test]
    fn sequential_runs_keep_separate_export_subdirs() {
        let tmp = tempfile::tempdir().expect("tempdir");
        let export_root = tmp.path().join("export_out");
        std::fs::create_dir_all(&export_root).unwrap();

        let src_a = tmp.path().join("only-a.txt");
        File::create(&src_a).unwrap().write_all(b"alpha").unwrap();
        let src_b = tmp.path().join("only-b.txt");
        File::create(&src_b).unwrap().write_all(b"beta").unwrap();

        let spec_a = tmp.path().join("spec-a.json");
        let spec_b = tmp.path().join("spec-b.json");
        write_spec(&spec_a, "seq-cell-a", "out.txt", &src_a);
        write_spec(&spec_b, "seq-cell-b", "out.txt", &src_b);

        let exe = supervisor_exe();
        assert!(
            exe.is_file(),
            "supervisor binary missing at {}",
            exe.display()
        );

        let run = |spec: &Path| {
            Command::new(&exe)
                .env("CELLOS_DEPLOYMENT_PROFILE", "portable")
                .env("CELL_OS_USE_NOOP_SINK", "1")
                .env("CELLOS_CELL_BACKEND", "stub")
                .env("CELLOS_EXPORT_DIR", &export_root)
                .current_dir(env!("CARGO_MANIFEST_DIR"))
                .arg(spec)
                .status()
                .expect("spawn cellos-supervisor")
        };

        assert!(run(&spec_a).success(), "first run failed");
        assert!(run(&spec_b).success(), "second run failed");

        let dest_a = export_root.join("seq-cell-a").join("out.txt");
        let dest_b = export_root.join("seq-cell-b").join("out.txt");
        assert_eq!(std::fs::read_to_string(&dest_a).unwrap(), "alpha");
        assert_eq!(std::fs::read_to_string(&dest_b).unwrap(), "beta");

        assert!(
            !export_root.join("seq-cell-b").join("only-a.txt").exists(),
            "run B subtree must not contain run A artifact file name by accident"
        );
        assert_eq!(
            std::fs::read_dir(export_root.join("seq-cell-a"))
                .unwrap()
                .count(),
            1
        );
        assert_eq!(
            std::fs::read_dir(export_root.join("seq-cell-b"))
                .unwrap()
                .count(),
            1
        );
    }
}