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

nordisk/edda

crates/nornir-release-core/src/lib.rs

//! # `nornir-release-core` — the shared release READ MODEL
//!
//! The PODs, the pure analysis and the portable gates that the release
//! *conductor* (dwarves) and the warehouse *owner* (nornir) both reason over.
//!
//! ## Why this crate exists
//!
//! Under PRE-PROMPT §L5a every constructive/publishing operation belongs to the
//! forge and the warehouse belongs to nornir. But the **model** the two halves
//! argue about — [`model::RepoGraph`], [`doctor::DoctorReport`],
//! [`model::SkewStatus`], [`doctor::DepPolicy`], the dep-DAG, the graph theory,
//! the portable [`gate`]s — is neither. It lived inside the forge, and nornir
//! reached it with a `dwarves = { path = … }` crate edge.
//!
//! That edge was the reason the forge could never compile nornir **in**:
//! `nornir → dwarves → nornir` is a cargo dependency cycle, and cargo rejects
//! those for normal deps regardless of features. Lifting the model to a leaf both
//! sides consume removes the edge in the `nornir → dwarves` direction, which is
//! what lets the forge embed nornir + skade for a real fat build.
//!
//! ## What is NOT here — deliberately
//!
//! Nothing constructive. `publish`, `promote`, `ramp`, `rehearse`, `preflight`,
//! `finalize`, `undo`, `dirty_sweep`, `iso_sandbox` and every `Cargo.toml`
//! MUTATOR stay with the conductor, which is the only process allowed to *do* a
//! release. This crate READS and JUDGES: it never edits a manifest, never spawns
//! a publish, never cuts a branch. [`cargo`] carries only the observing half
//! (which binary, what changed, what must be re-tested).
//!
//! ## The warehouse seam
//!
//! The warehouse-coupled legs ([`doctor`], [`semantic_blast`], [`skew_warehouse`],
//! [`knowledge`]) name the warehouse **only** through the engine-agnostic
//! `nornir_warehouse_trait::Warehouse` trait and its POD rows — never a concrete
//! `IcebergWarehouse`. That is precisely what lets a leaf host them.
//!
//! ## Map
//!
//! | module | what it answers |
//! |---|---|
//! | [`model`] | the shared PODs: skew, repo graph, patch-fork promote gate, preflight issues |
//! | [`graph_math`] | pure graph theory: Tarjan SCC, condensation → publish waves, MFAS cycle cuts |
//! | [`doctor`] | the read-analysis + report engine over those PODs |
//! | [`gate`] | the portable release gates (path-dep audit, crate metadata, no-regression, …) |
//! | [`depdag`] | the crate-level release dep-DAG (nodes = crates, edges = depends-on) |
//! | [`registry`] | what version is actually PUBLISHED (sparse index, pure `ureq`) + the probe seam |
//! | [`edition`] | static Rust-2024 / cargo-standards findings |
//! | [`semantic_blast`] | which dependents a changed symbol breaks (the call-graph blast radius) |
//! | [`api_skew`] / [`skew_warehouse`] / [`published_ingest`] | "we call a symbol published D does not export" |
//! | [`shadow_solve`] / [`version_solve`] / [`depgraph_trait`] | the independent cross-checks on the plan |
//! | [`progress`] | the release-run progress ledger |
//! | [`cargo`] | the observing half of the cargo leg |
//! | [`source_drift`] | same-version "edited without a bump" (re-export of `nornir-release`) |

/// Shared release PODs + the PURE closure the analysis reasons over: the skew types
/// (`CrateSkew`/`RepoCrateStatus`/`SkewStatus`), the patch-fork promote gate
/// (`compute_promote_block` + `PatchForkBlock`/`HeldExplanation`/`PromoteBlockResult`),
/// the cross-repo `RepoGraph` facts, and the preflight `Issue`/`IssueKind` PODs.
/// Filesystem-only (walks `Cargo.toml`); no warehouse.
pub mod model;
/// Pure graph-theory + optimization core: Tarjan SCC, condensation → publish waves,
/// MFAS cycle-cut ranking, and the invertive remedy planner over the outcome-space Ω.
/// Deterministic (BTree-ordered), no I/O, independent of how the graph was extracted.
pub mod graph_math;
/// Same-version SOURCE-DRIFT detection (re-export of the shared `nornir-release`
/// leaf): a crate whose local source differs from the copy already published at the
/// same version (the "edited without a bump" trap).
pub mod source_drift;
/// FORWARD api-skew PODs: "member M calls a symbol the PUBLISHED dep D does not
/// export". Pure set reasoning over already-extracted symbol names.
pub mod api_skew;
/// The published-crate API surface reader: unpack a published `.crate` tarball and
/// extract the `pub` surface, so the skew join has a right-hand side.
pub mod published_ingest;
/// WAREHOUSE-NATIVE api-skew — the *Mimir join* form of [`api_skew`], stated as a
/// relational ANTI-JOIN over already-extracted PODs (member `call_edges` vs the
/// ingested published-dep `symbol_facts`) instead of a re-scan of source.
pub mod skew_warehouse;
/// The call-graph MODEL of the SEMANTIC-BLAST analysis (`KnowledgeView`), from the
/// shared `nornir-knowledge-view` leaf; never twinned. Its readers of
/// `scip_occurrences` / `symbol_facts` / `call_edges` are gone with their writers.
pub mod knowledge;
/// SEMANTIC BLAST RADIUS: which dependents does a changed/removed exported symbol
/// break, and which of those are hard *link errors* rather than mere behaviour drift.
pub mod semantic_blast;
/// Registry-state check (crates.io sparse index / custom base URL, pure-Rust `ureq`):
/// what version is actually PUBLISHED, the local-vs-published class, and the injectable
/// [`registry::RegistryProbe`] seam the order analysis probes through.
pub mod registry;
/// The crate-level release dep-DAG: nodes = crates, edges = depends-on, states =
/// published / local-ahead / blocked. The seed the release UI panes render.
pub mod depdag;
/// Static Rust-2024 / cargo-standards findings (edition, resolver, MSRV advisories).
pub mod edition;
/// The abstract `DepGraph` seam + the in-memory petgraph backend, so the same
/// questions can later be asked of a graph database without moving the callers.
pub mod depgraph_trait;
/// The PubGrub-style interval CSP over version requirements — "does a version
/// assignment actually satisfy every constraint in the graph?"
pub mod version_solve;
/// An INDEPENDENT re-derivation of the release plan (a shadow solve), so a bug in
/// the primary linearization shows up as a disagreement rather than a bad release.
pub mod shadow_solve;
/// The read-analysis + report ENGINE over [`model`]'s PODs: skew analysis, cycle
/// detection + advice, publish order/waves, the cross-repo `RepoGraph` gatherer, and
/// the rendered `DoctorReport`.
pub mod doctor;
/// The PORTABLE release gates — path-dep audit, crate metadata, links declarations,
/// no-regression over bench history, nexus floor, integration round-trip, published
/// git-tag match, guard-manifest integrity — plus the `GateDispatch` router.
pub mod gate;
/// Release-run progress ledger.
pub mod progress;
/// The READ-ONLY half of the cargo leg: `cargo_bin`, the changed-crate diff, and the
/// reverse-dependency closure that must be re-tested.
pub mod cargo;
/// The before→after DEP-GRAPH DIFF: neutral `(name, version)` / `(from, to, req)`
/// snapshots, the classified node bumps + edge req-changes, and the two warehouse row
/// shapes (`semver_diffs`, `dep_graph_edges`). Pure — the content-addressed ARTIFACT
/// lowering that publishes a diff into a release run stays with the conductor.
pub mod graph_diff;
/// The ecosystem-neutral release VOCABULARY — `Package`/`Variant`/`Dependency`/
/// `ResolvedPin`/`Artifact` PODs and the [`ecosystem::ApiCompat`] verdict. Pure — the
/// `Ecosystem` trait (whose verbs BUILD and PUBLISH) and its Cargo/Maven impls stay
/// with the conductor.
pub mod ecosystem;

#[cfg(test)]
mod testkit;