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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//! # nornir
//!
//! A project-agnostic companion to `cargo`. Reusable building blocks
//! for release pipelines, benchmarks, and documentation written in
//! Rust, callable from thin per-project driver binaries.
//!
//! Modules:
//! - [`bench`] benchmark harness + append-only JSONL history
//! - [`release`] gates, publish-order walker, deploy
//! - [`deps`] cross-crate dependency tracking (workspace-aware)
//! - [`docs`] deterministic assembly of README / CHANGELOG / etc.
//! - [`guard`] AI-agent guard rails: chmod -w forbidden paths
//! declared in `[guard].forbidden` of a nornir.toml
//! - [`introspect`] call graph + dep graph + public API extracted from
//! the *built* code (rustdoc JSON, cargo metadata, syn);
//! rendered into docs so they cannot drift from the code
//!
//! Optional features:
//! - `fixtures-maven` — canonical Maven Central JAR set as bench inputs
//!
//! Future companion crates (not in this repo):
//! - `nornir-mcp` — exposes every API here as an MCP (Model Context
//! Protocol) tool, letting an LLM agent drive build/release/docs.
//! - `nornir-cli` — `cargo nornir ...` subcommand for human use.
//!
//! See `workspace_holger/release/SPEC.md` for the contract that
//! generated binaries implement on top of this library.
// The viz app's whole-app `state_json()` is one large `serde_json::json!`
// object literal (one tab pane per key); each entry costs a level of the
// `json_internal!` macro recursion, so the default limit of 128 is exceeded once
// the tab set grows. 256 gives ample headroom for the pane keys.
// Self-alias so modules that are `#[path]`-shared with the integration-test
// crates (where the library is an EXTERNAL `nornir::` dependency) — notably the
// synthetic-workspace generator included by [`bench_registry`] — resolve their
// `nornir::…` paths identically when compiled INTO this crate. Without it,
// `nornir::gitio` is unresolvable inside the lib (a crate is not a dependency of
// itself).
extern crate self as nornir;
// nornir's OWN benchers, registered via `register_bench!` so `inventory` links
// them into the lib (and thus into the completeness-gate binary). See the module
// docs: the discovery seam `nornir_bench::api::registered_bench_ids()` can only
// see benchers that are LINKED, so the registrations must live here, not in the
// `examples/nornir-bench.rs` runner (an example is not linked into the lib).
// Lifted into the `nornir-bench` leaf crate (its cli_outcome coupling is via
// nornir-cli-outcome; the live progress trail writes $NORNIR_VIZ_ACTIONLOG
// directly, so no viz/egui dep is pulled in); re-exported (with the
// `register_bench!` / `register_bench_ordered!` macros) so every
// `crate::bench::…` call site resolves unchanged.
pub use nornir_bench as bench;
pub use ;
// Host wiring for the `brokkr` CI/build-server core: the CI_BUILD job
// orchestrator + history store + the DemoRunner. The pipeline model/DAG/engine
// live in the dep-light `brokkr` leaf crate; this is the nornir-only glue.
// Lifted into the `nornir-cli-outcome` leaf crate (pure serde); re-exported so
// every `crate::cli_outcome::…` call site resolves unchanged.
pub use nornir_cli_outcome as cli_outcome;
// Lifted into the `nornir-coverage` leaf crate (cargo-llvm-cov run/report, pure
// serde; its warehouse/module couplings were doc-links only — the Iceberg
// persistence stays in nornir); re-exported so every `crate::coverage::…` call
// site resolves unchanged.
pub use nornir_coverage as coverage;
/// Graph extraction — the one `G = (V, E)` model fed by both a source extractor
/// (manifests / SCIP) and a **binary extractor** ([`graph::extract::binary`],
/// ELF → `G`) for the airgap / vendored-`.so` case (EPIC item 8).
// Lifted into the `nornir-git` leaf crate (gix + russh transport, no warehouse/
// embedder deps); re-exported so every `crate::gitio::…` / `crate::gitclean::…` /
// `crate::ssh::…` call site resolves unchanged.
pub use ;
// Lifted into the `nornir-guard` leaf crate (anyhow + sha2, its only cross-crate
// coupling is nornir-cli-outcome); re-exported so every `crate::guard::…` call
// site resolves unchanged.
pub use nornir_guard as guard;
// Lifted into the `nornir-jobs` leaf crate (redb ledger + serde; its warehouse
// couplings were doc-links only — the concrete Iceberg persistence stays in
// nornir); re-exported so every `crate::jobs::…` call site resolves unchanged.
pub use nornir_jobs as jobs;
// Lifted into the `nornir-selftest` leaf crate (bridges nornir-testmatrix);
// re-exported (with the `assert_emit!` macro) so every `crate::selftest::emit`
// and `assert_emit!` call site resolves unchanged.
pub use nornir_selftest as selftest;
pub use assert_emit;
// `ssh` moved into the `nornir-git` crate (re-exported above with gitio/gitclean).
// `viz` builds the full egui app; `server` needs only `viz::model` (the pure
// timeline builder) for the `Viz.Timeline` RPC — submodules are gated inside.
pub use ;
/// Process-wide serial lock for tests that mutate GLOBAL state (env vars, cwd, or
/// spawn `cargo metadata`). `cargo test` runs tests multi-threaded by default, so
/// two tests touching the same `HOME`/`NORNIR_VIZ_ACTIONLOG`/`cargo`-lock race
/// intermittently (each passes alone). Such tests take `let _g = nornir::serial_guard();`
/// at the top so they run one-at-a-time relative to each other. Poison-tolerant.
pub