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

nordisk/korp-collectors

.nornir/runtime-substrate-design.md

Runtime substrate trait — the interface (design)

korp_collectors::runtime (feature daemon) is the object-safe interface that decides WHERE a collector daemon (or, later, a knut pipeline) runs, decoupled from its logic. A collector's behaviour is substrate-agnostic (Collector against CollectorCtx); this trait is the seam that spawns it. See the workspace design runtime-aortas-design-2026-07-29.md.

Leaf discipline

This crate depends on neither korp nor jera nor kube, so the trait pulls no new deps — pure serde + anyhow (both already under daemon). The concrete implementations (JeraRuntime, KubeRuntime) live in korp, which owns jera / aegir / skidbladnir. Keeping the interface here lets both korp and facett-demo consume it without the facett ⇄ korp cycle.

The shapes

The trait

pub trait Runtime: Send + Sync {
    fn kind(&self) -> RuntimeKind;
    fn start(&self, spec: &UnitSpec) -> Result<Handle>;   // idempotent where the substrate allows
    fn stop(&self, h: &Handle) -> Result<()>;             // idempotent
    fn status(&self, h: &Handle) -> Result<RunStatus>;
    fn reconcile(&self, desired: &[UnitSpec]) -> Result<()>; // the Settings toggle / matrix ▶Run route
}

Object-safe (&self, no generics), so a Box<dyn Runtime> selects the substrate at runtime from the persisted per-collector choice. Proven by a mock in the crate tests (runtime_is_object_safe_via_a_mock) plus key/serde round-trips.