1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//! Release gates, publish-order walker, deploy.
//!
//! Each gate is a free function returning `Result<()>`. Generated
//! release binaries call them in the order defined in
//! `workspace_holger/release/SPEC.md`.
/// Release dependency-DAG (crate publish-order graph) assembled as a neutral graph
/// model annotated with per-crate registry state — the deep half of the release
/// dep-DAG viz surface.
/// Graph-theory + optimization core the doctor reasons over: Tarjan SCC,
/// condensation → publish waves, MFAS cycle-cut ranking, and the invertive
/// remedy planner over the outcome-space Ω. Pure, deterministic, extractor-agnostic.
/// Pre-cascade validation (catch ALL blockers before any irreversible
/// `cargo publish`): non-members, missing crates.io metadata, dep-API skew (via
/// `--dry-run` verify), detached workspaces, and registry/version consistency —
/// aggregated into one "preflight: N blocking issue(s)" summary with per-issue fixes.
/// Registry-state check (item #10): a pluggable [`registry::RegistryBackend`]
/// (crates.io sparse-index default, custom/private base URL, both pure-Rust
/// `ureq`) that asks the registry "what version is actually PUBLISHED?" and
/// classifies each publish target local-vs-published — catching the
/// local-behind-registry DESYNC (`gatling` 0.1.4-local vs 0.1.6-published)
/// that today's verify-only preflight lets slip through and tear the cascade.
/// Topological ROOT-CAUSE analysis (item #9): partition a flat failure list from
/// the publish/preflight cascade into the ROOT crate(s) and the downstream
/// symptoms each root explains, so the operator fixes the one un-published
/// dependency instead of chasing N dependents' verify failures.
/// Same-version SOURCE-DRIFT detection: a crate whose local source differs from
/// the copy already published at the same version (the "edited without a bump"
/// trap) — a hard preflight blocker, and the inverse (unchanged ⇒ skip republish).
/// Semantic blast radius (EPIC item 7): cross-reference a version bump against the
/// warehouse SCIP call-graph to find the EXACT call sites that touch the changed
/// crate's API — "what actually breaks", not merely "who depends on it".
/// `nornir release undo` (task #32): reverse a release run's mutating steps from
/// the `release_changes` ledger (un-bump, restore `[patch]`, delete/reset branch,
/// yank an immutable publish) + the record wrappers the release path drives.
/// Loud deprecation banner for the release **ACT** verbs (build / publish / gate /
/// prepare / reverse steps). Per ratified doctrine (PRE-PROMPT §L5a, 2026-07-14 —
/// *release is a build op*) release ORCHESTRATION moved to `dwarves release`; the
/// nornir release ACT verbs are retained as still-working shims that warn on use.
/// The read-only warehouse VIEW / lineage verbs (regression trace, event DAG,
/// changelog, impacted-crate report, undo-ledger) stay in nornir and do NOT warn.
///
/// Factored out here (a pure `&'static str`) so the banner is unit-testable
/// without running a real publish. Must always mention `dwarves release`.