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

nordisk/holger

xtask/Cargo.toml

[package]
name = "xtask"
workspace = "../estate"
version.workspace = true
license = "AGPL-3.0-only"
edition = "2021"
publish = false

[dependencies]
serde_json = "1"
# The front medium's `clock=` sources (`estate_clock::config::CLOUD_SOURCES`, shared with
# Gunnar's kit, lane G3). Default features: constants and parsing only — no socket, no crypto.
estate-clock = { version = "0.1.1" }
anyhow = "1"
# `cargo xtask ci`: the shared plan runner, receipt and lock check (std only), and the
# shared spawn guard (`spawn_guard`, 0.1.5 on crates.io; RA4-7). The estate's sibling
# patch provides it from ../edda.
nornir-xtask-support = "0.1.5"
# Proto codegen — runs ONLY here in the xtask (`cargo xtask gen-proto`), never in
# any build.rs. protox is the pure-Rust protobuf compiler (no `protoc` binary, no
# subprocess): it parses `proto/holger.proto` → FileDescriptorSet, which we feed to
# tonic-build's `compile_fds` to emit the committed `server/lib/src/generated/holger.v1.rs`.
# A normal `cargo build` then compiles ONLY the checked-in generated code — no protoc.
protox = "0.10"
tonic-prost-build = "0.14"

# Holger's build-space (the three deployment tiers as data) + nornir's build-thing
# core. The `build` verb reflects the BuildSurface (`build --list`) and presses a
# tier end-to-end (`build --variant <tier>` → shell cargo + attest). This is
# holger's own first-party tooling driving its declared build tiers — the seam that
# was previously reachable only through the never-run example.
holger-build-space = { path = "../build-space", version = "3.0.0" }
# `cargo-container` is the EXECUTION LEG of the `build` verb: `cargo_container::
# build_variant_in_container` + `DraupnirCargoRunner`, the draupnir backend-oci
# engine the kernel kind and korp-installer's compose already drive. Without it
# `build` shells host cargo, and `mvp-server-musl` (x86_64-unknown-linux-musl)
# then depends on whether the box happens to own a musl cross-gcc — MEASURED on
# loki 2026-09-17 in gunnar, which has the identical shape: the host build died
# in aws-lc-sys on a missing `x86_64-linux-musl-gcc`. The feature is off by
# default upstream so a leaf consuming only the TYPES stays dep-light; this
# crate is the consumer that actually runs a build container.
nornir-build-thing = { version = "0.2.6", features = ["cargo-container"] }
# The DECLARATION itself: `installer-iso` resolves `--variant` against the Rust
# code and refuses to compose from a committed toml that is not its emission.
#
# The default feature set includes `gate` — `holger_recipe::honesty`, the offline
# rule engine `cargo xtask gate` runs, plus the bench-driver list RULE 3 builds.
# That is declaration knowledge (which rows ship, which crates are bench-only,
# which drivers publish numbers), so it lives in the recipe and xtask stays a door.
holger-recipe = { version = "3.0.0", path = "../holger-recipe" }

# `cargo xtask test` builds the wasm guests with the same helper the guards use
# (`traits::test_support::wasm_guest`), into the same directory.
traits = { package = "holger-traits", path = "../traits", features = ["test-support"] }

# The appliance-pack verb: the shared znippy codec (the ONE archive writer —
# `create_archive_to_vec`/`get_file`, the same pair korp-installer's
# pack_znippy wraps and korp-start verifies with) + blake3 for the pin file
# the installer medium carries beside the payload.
znippy-common = { version = "0.10.4" }
blake3 = "1"
# `cargo xtask scan-worker stage` (lane HOLGER-MEDIA): the sandbox entries every main/twin
# medium carries in its app archive (the worker rootfs tar, the pinned static crun, the
# flattened ClamAV rootfs, the manifest): the types and the tar builder are the sandbox crate's.
holger-sandbox = { version = "4.0.1", path = "../server/sandbox" }
# The staging manifest (`scan-worker stage`) is TOML, read back by the box.
toml = "1"

# The estate-media verb (lane L21): the release bucket's SigV4 PUT (sha2 + hmac, the pair
# Gunnar's kit signs with) over ureq — the media and live apps of Holger's release.
sha2 = "0.11"
hmac = "0.13"
ureq = { version = "3", default-features = false, features = ["rustls"] }
# `cargo xtask installtest` (lane P5): the airgap box takes its advisory database the way an
# airgap estate does, as a signed `holger.intel/v1` bundle at `POST /-/intel/import`; the test
# mints the signers (rcgen, ed25519), the trust policy and the bundle itself.
holger-intel = { version = "3.1.1", path = "../intel" }
update-bundle = { package = "holger-update-bundle", version = "3.0.0", path = "../update-bundle" }
rcgen = "0.14"

# The installer-iso verb: edda's ONE installer composition (isocompose behind
# `forge`) + the KVM proof harness, plus `secure-boot` so `--sign` can
# Authenticode-sign the firmware-loaded PEs through the crate's ONE signer.
#
# ⚠ THE REQUIREMENT IS EXACT, AND IT HAS TO BE (2026-09-21, lane H2). This read
# `version = "0.1.7"` with a comment saying "0.1.7, the version edda main
# carries". `"0.1.7"` is `^0.1.7`, the lock had resolved **0.1.13**, and nothing
# anywhere compared the two — six patch releases of the crate that writes the
# partition table, elects the boot disk and stages the per-site declarations,
# taken silently. That is the SAME caret class of bug this very manifest already
# records twenty lines down ("`^0.1` can never reach 0.5.x, so this resolved
# nornir 0.1.0"), unapplied one line above it.
#
# The `path` is what cargo actually takes — the sibling checkout always wins, and
# nothing here can pin a working tree. What the exact requirement buys is that a
# checkout which has moved on is a BUILD-TIME REFUSAL naming both versions,
# instead of a silently different installer under a medium nobody rebuilt.
# `holger-recipe/tests/installer_pin.rs` holds both halves.
#
# MOVED AGAIN 0.1.18 -> 0.1.19 on 2026-09-23, hours after the first move, and
# that is the pin WORKING rather than a defect. edda main 6713696 published
# korp-installer 0.1.19, and this exact requirement refused by name with both
# numbers in it:
#
#     error: failed to select a version for the requirement `korp-installer = "=0.1.18"`
#     candidate versions found which didn't match: 0.1.19
#
# That refusal is the whole point of spelling it exactly. A pin that is planned
# to move is not a defect; a pin DISCOVERED to have moved is.
#
# MOVED 0.1.13 -> 0.1.18 on 2026-09-23. The pin did its job and then became the
# problem: edda main carries korp-installer 0.1.18 and the gunnar estate is
# pinned to 0.1.18, while this exact requirement held holger at 0.1.13. dwarves
# resolves its workspace with holger as a sibling, so the whole dwarves lock was
# dragged BACKWARDS to 0.1.13 (and nornir-build-thing to 0.1.20), a `--locked`
# build of dwarves could not resolve at all, and nothing could be released from
# a tree resolved that way. A pin that is five patch releases behind the crate
# that lays down the boot disk is not a pin, it is a retired installer.
#
# MOVED REPO 2026-09-26 (owner ruling): korp-installer lives in TUNNR now, next to
# the kernel it boots (tunnr/tunnr-kernel). Same crate, same version; only the
# sibling path changed from ../../edda/crates to ../../tunnr/crates.
#
# 0.1.19 -> 0.1.20, 2026-10-02: tunnr main is at 0.1.20, so the =0.1.19 pin no
# longer resolved against the sibling at all (same failure mode as above).
#
# 0.2.7 -> 0.2.8, 2026-10-27 (R6-FIX-1): tunnr 60e32dd3 is 0.2.8 (published in R5B), and
# installtest refused `[installer-source-not-the-pin]` while the root lock said 0.2.7.
# 0.2.10 -> 0.2.11, 2026-11-01 (HOL-CDS-6): crates.io korp-installer 0.2.11 (tunnr 2fc7d74),
# wg-appliance-core behind the default-on `wg-identity`; forge keeps it, so this xtask is unchanged.
korp-installer = { version = "=0.2.12", features = ["forge", "secure-boot"] }
# nornir-testmatrix — TWO jobs in xtask, and only one of them is optional.
#
# 1. NOT optional, since 2026-09-20: `gate` phase 5 needs `gatedtests::audit_repo`
#    (which test targets compile to an empty binary and print `ok`) and
#    `runner::run_arms` (RUN every declared rescue arm). Both are default-feature
#    API. It was optional until the day the gate learned to run the arms, and the
#    six silenced security guards that day found are the argument for the change:
#    a phase that only exists under `--features testmatrix` would be one more
#    guard nothing turns on.
# 2. The functional-status EMITTER stays behind `--features testmatrix`
#    (`nornir-testmatrix/testmatrix`), so the per-verb emit calls in `main.rs` are
#    still compiled OUT of an ordinary xtask build. xtask is `publish = false` and
#    ships in nothing, so the dep itself costs no artifact.
#
# The same crate is also a [dev-dependency] below for `holger_matrix`s grid model.
[dependencies.nornir-testmatrix]
# The PATH to the sibling edda checkout, like build-space and mannequin: registry
# 0.2.9 carries the `gatedtests` module (so the silenced-test guard compiles
# against it) but NOT `runner::run_arms`, which gate phase 5 needs to EXECUTE a
# declared arm. The workspace already resolved this crate TWICE for exactly that
# reason -- the hazard the root Cargo.toml names -- so xtask joins the one source.
version = "0.2.13"

[features]
# `korp-installer/testmatrix` rides along because the appliance ISO rows are
# emitted by the SHARED harness (`korp_installer::isoproof`), not by holger's
# test files: it owns the `<product>-appliance/iso-kvm` component string, so no
# product can spell the form as plain `iso` and let a KVM green pass for metal.
testmatrix = ["nornir-testmatrix/testmatrix", "korp-installer/testmatrix"]

[dev-dependencies]
tempfile = "3"
# estate-media's receipt read back as the ONE kit reads it.
# The fleet proof's HUB: wg-appliance-core's HubFixture — reserve the hub's
# identity/port BEFORE mastering (the ISO bakes hub.conf), activate per
# appliance key after its first boot. The same fixture the container robot
# proves tunnel-up with — one hub implementation, both shapes.
wg-appliance-core = { version = "0.1.5" }
# The fleet proof's PLANNER: draupnir's plan_fleet fans ONE per-site ISO spec
# into N machine specs (the brief's "same spec that provisions real metal
# drives the tests"). Default features only — pure std; the KVM boot leg rides
# korp-installer's kvmproof (draupnir's KVM backend cannot boot an ISO, see
# draupnir/.nornir/iso-to-fleet.md). Path-only: dev tooling, unpublished pin.
draupnir = { version = "0.2.0" }
# ⚠ WAS `nornir = "0.1"` — and `^0.1` can never reach 0.5.x, so this resolved
# nornir 0.1.0 off crates.io: an ancient published copy that drags `iceberg 0.9.1`
# (stock, NOT skade's arrow-59 fork) and `parquet 57.3.1` with it. That single
# caret was the ONLY reason arrow 57 was still compiled anywhere in the
# constellation — every other repo resolves arrow 59.2.0. Not optional, not a
# dev-dep: it was really being built. Corrected 2026-08-24.
#
# ⚠ DROPPED 2026-09-20 (?37). `nornir = "0.5"` was used by exactly ONE file,
# `xtask/examples/nornir-bench.rs`, and only for `nornir::bench::*` +
# `nornir::register_bench!` — which are re-exports of `nornir-bench`. Keeping the
# warehouse on the edge pulled registry `holger-server-lib 0.6.10`, which pulled
# 24 more holger crates: 25 holger crates appeared TWICE in `Cargo.lock`, once
# from this tree and once from crates.io. holger's own test graph was building
# holger's PUBLISHED SELF. The example now depends on `nornir-bench` directly,
# which is the crate that actually owns the bench surface (LAW 5, reuse the leaf
# rather than the warehouse that re-exports it).
#
# Option (b) from ?37 — `[patch.crates-io] holger-server-lib = { path = ... }` —
# was NOT taken: it touches the publish gate, and the release procedure's step 1
# is "remove all [patch.crates-io] overrides".
nornir-bench = { version = "0.2.0" }
anyhow = "1"
serde_json = "1"
blake3 = "1"
holger-bench-scenarios = { path = "../bench-scenarios", features = ["nexus", "artifactory", "promote-ledger", "retention-planner", "audit-append", "secure-update", "stress", "hops", "grpc-door", "intake", "sandbox"] }
# tokio runtime for driving the async, fixture-gated Nexus-comparison benchers
# from the sync `Bencher::run()` contract (build a runtime + block_on).
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time"] }
# The nordisk multi-aspect test-matrix engine (Build/Unit/Doctest/Clippy/… with
# a TestSink + the `functional_status` emitter read back via JsonFileSink). holger's
# per-component green/red grid + the mannequin row + the functional-emitter cell
# are driven through it. `tests/holger_matrix.rs`. Resolved locally via the
# workspace [patch.crates-io] until 0.2.0 lands on crates.io.
nornir-testmatrix = { version = "0.2.13" }