crates/knut-build-thing/Cargo.toml
# knut's **build thing** — the recipe, as a crate. CODE IS THE SOURCE.
#
# ## What changed on 2026-09-20, and why the crate has a new name
#
# This crate used to be `knut-build`, and it was the EXACT INVERSION the law
# forbids: `src/lib.rs` carried
#
# const VARIANTS_TOML: &str = include_str!("../build-variants.toml");
# … BuildVariantSet::from_toml_str(VARIANTS_TOML)
#
# — the hand-written toml was COMPILED IN and READ BACK AS AUTHORITY, and the
# Rust was a thin reader of it. dwarves/.nornir/build-thing-code-is-source-design.md
# (2026-08-27) says the opposite and says it one-directionally: the `impl
# BuildThing` is the one source, and `.nornir/build-variants.toml` is EMITTED from
# it to DESCRIBE the build. knut and edda were the last two repositories still
# the wrong way round; this is knut's turn.
#
# The RENAME is not cosmetic and not a preference. dwarves' forge finds a repo's
# recipe by package name — `dwarves::build_thing::code::recipe_crate`, `SUFFIX =
# "-build-thing"` — trying `<repo>-build-thing` first and then any package under
# `crates/` or the root that carries the suffix AND is a `cdylib`. `knut-build`
# carried neither, so knut's CODE ROAD WAS CLOSED BY NAME: the forge could only
# ever fall back to reading the emitted toml as if it were the source, which is
# the very drift being removed. Two packages with the suffix in one repo is
# refused as ambiguous, so this is a rename and not an addition.
#
# ## The dependency is the REGISTRY, and that is load-bearing for knut
#
# Every recipe crate turned this week (draupnir, ordning, Skidbladnir, skade …)
# path-deps `../../../edda/crates/nornir-build-thing`. knut MUST NOT: that exact
# line was measured on 2026-09-10 as one of the two escapes that made a bare
# `git clone knut && cargo build` fail to load the WHOLE workspace on any box
# without the sibling checkout ("failed to load manifest for workspace member
# crates/knut-build … dependency nornir-build-thing"). A path dep is read at
# manifest-load time, so its absence is not a missing feature, it is a workspace
# that will not resolve at all.
#
# `nornir-build-thing 0.1.18` is ON CRATES.IO and carries everything this recipe
# needs — `emit` (the one `code → toml` writer, byte-identical to edda's working
# copy), `BuildVariantSet::base_suite`, `CargoToolchain`, `BuildVariant::
# manifest_dir` rendered as `--manifest-path`, `consequence::feature_consequence`
# and `laws::assert_bijective`. So nothing had to be published to turn knut
# around, and the bare-clone property is kept.
[package]
name = "knut-build-thing"
version.workspace = true
edition.workspace = true
license.workspace = true
authors.workspace = true
# Inherited like every other knut member. Its absence was the one `MissingMetadata`
# finding in the repo's release gate — crates.io takes the upload without it, so
# nothing fails; the crate just lands with no link back to its source.
repository.workspace = true
description = "knut's build thing: the six rows knut ships (knutpipe · knut-spark-server · graphar-flight · bifrost · knut-popviz · the wasm32 transform guest) declared as typed Rust, plus the two rules only knut knows — that four of its five binaries carry `required-features` (so a plain `cargo build --all-targets` silently produces one of them), and that the popviz GUI transitively autostarts a FalkorDB. `.nornir/build-variants.toml` is emitted from this code and never read back."
# Not published. The recipe is knut's own declaration, nothing outside this
# repository resolves it, and `publish = false` is what every other recipe crate
# in the constellation says. `knut-build` (this crate's old name) was publishable
# by inheritance and nothing ever depended on it from the registry — measured
# across ~/git: the only mentions are two prose lines in holger's manifests.
publish = false
[lib]
# `cdylib` is the wasm32 module the dwarves forge loads (a recipe crate that is
# not a cdylib is REFUSED BY NAME by `dwarves::build_thing::code`); `rlib` is the
# native library the tests and the emit bin link. One source, no `cfg` fork.
crate-type = ["cdylib", "rlib"]
[[bin]]
# The emit door: `knut-build-thing emit` regenerates .nornir/build-variants.toml
# from `variants()`; `--list` prints the roster; `toml` prints the emission.
name = "knut-build-thing"
path = "src/main.rs"
[dependencies]
# The contract, the declaration types, the `plugin::BuildThing` trait and the ONE
# `code → toml` emitter (`nornir_build_thing::emit`). From the REGISTRY — see the
# header for why knut cannot take the sibling path every other recipe takes.
# 0.1.14 → 0.1.18: 0.1.14 predates `emit`, so under the old pin there was no
# writer at all and the file could only be hand-kept, which is how this crate got
# the way it was.
nornir-build-thing = { version = "0.1.20", default-features = false }
anyhow = { workspace = true }
[dev-dependencies]
# The silenced-test guard (`tests/silenced_tests_guard.rs`): edda's
# `nornir_testmatrix::audit_repo` walks every `tests/*.rs` in the workspace and
# fails when one is dark behind an off-by-default `#![cfg(feature = ...)]`.
# Registry, and the version is honest: a dev-dep never leaks into consumers.
nornir-testmatrix = { version = "0.2.11", default-features = false }
# `tests/typed_consequence.rs` reads the member crates' own `[features]` tables
# and holds the recipe's declared FEATURE TABLE to them. A test may read the
# filesystem; the recipe may not (the wasm sandbox grants no fs), which is why
# the manifest reading lives here and the declaration lives in `recipe.rs`.
toml = "1"
[build-dependencies]
# The recipe's own content hash over its sources (`build.rs`): a receipt names
# the recipe by `krate:version:hash`, and the hash is the only field that tells
# two builds of the same version apart.
sha2 = "0.11"