nornir-release — the warehouse-free release detectors (leaf)
The reusable, warehouse-free slice of nornir's release engine, lifted into edda so release logic lives in one place (Law #1) and the release command can move to dwarves without copying code.
f0 — what it is
source_drift— the source-drift detector: fetch the published crate tarball (ureq), unpack (flate2/tar), parse (toml), hash + compare against the local source →assess/can_skip_republish/summarize_differing. Std + those four leaf crates only; a privatecargo_bin()(env/~/.cargo/rustup) keeps it self-contained.waves— the pure publish-wave planner (zero I/O, std-only): the deps-first, parallel-publish order of a workspace.plan_waves(&[WorkspaceCrate]) -> PublishWavesdropspublish = falsemembers, keeps only intra-workspace publish-gating edges (Normal/Build, neverDevelopment— cargo strips dev-deps at publish time, so counting one invents false cycles), and Kahn-layers the DAG into parallelphases(a whole wave publishes at once), surfacing any real dependency cycle incyclicrather than dropping it.topo_phases(members)is the low-level drop-in matching nornir's historic private helper (cycle remainder appended as a final phase). This is the logic half of the release engine — thecargo metadataread + thecargo publishwalk stay in the conductor (nornir); nornir mapscargo_metadata::DependencyKind → waves::DepKindand feedsWorkspaceCrates in, dwarves drives the same primitive over gRPC. Nocargo_metadatadep pulled into the leaf.
f1 — self-emitter (testmatrix)
Behind the testmatrix feature (dep:nornir-testmatrix, release strips it), selftest::emit pushes a functional row per real plan_waves surface (deps-first ordering, real-cycle verdict) so nornir test --features testmatrix records the planner behaves — drained and asserted in the gated wiring test.
Why only this moved (and the rest did NOT)
doctor / gate / preflight read nornir's Iceberg warehouse (crate::warehouse::…, gate alone = 12 refs). edda is a leaf nornir depends on, so moving warehouse-reading code here would invert the graph → cycle. Those stay in nornir. The CI/CD split is achieved differently: the release command moves to dwarves and calls nornir's warehouse-reading engine over gRPC (command→dwarves, warehouse→nornir, pure detectors→edda). See workspace_nordisk/.nornir/code-placement.md.
Consumers
- nornir —
src/release/source_drift.rsis now apub use nornir_release::source_drift::*;re-export, so everycrate::release::source_drift::…call site is unchanged. - dwarves (future) — the
releasecommand consumes the same crate for skip-unchanged.