xtask/tests/engine_seam.rs
//! **The engine-seam guard's own red, then its green.**
//!
//! A check that has never been seen to fail is not a check. Every rule
//! in [`xtask::engine_seam`] is fired here against the code **as it actually
//! stood at `e80f175`** — the real prior text, copied out of `git show`, not an
//! invented sample — and then the same rules are run over the tree and asserted
//! clean with a non-zero file count.
//!
//! The prior text matters more than usual for this one. The defect it guards
//! against had **no call sites**: five `pub` items merely *naming* a pack
//! implementation kept `gix-pack` and ten more gix crates in the appliance
//! graph for five days. A synthetic sample would prove the regex works; the
//! real lines prove the rule would have caught the thing it is named after.
use xtask::engine_seam::{check_manifest, check_source, scan, Rule};
/// `gunnar-wire/Cargo.toml` at `e80f175`, verbatim from `git show`. This one
/// line is the whole five-day defect: no call behind it, and `gix-pack`,
/// `gix-diff`, `gix-traverse`, `gix-revwalk`, `gix-commitgraph`, `gix-fs`,
/// `gix-tempfile`, `gix-path`, `gix-chunk`, `gix-zlib` and
/// `gix-features/parallel` in front of it.
const WIRE_MANIFEST_BEFORE: &str = "\
[dependencies]
gunnar-pktline = { workspace = true }
gunnar-pack = { workspace = true }
gunnar-store = { workspace = true }
";
/// `gunnar-server/Cargo.toml` at `e80f175`, verbatim. Four gix crates, and only
/// the fifth (`gix`, the porcelain) was ever optional.
const SERVER_MANIFEST_BEFORE: &str = "\
[dependencies]
gunnar-grpc = { workspace = true }
gunnar-pack = { workspace = true }
gix-hash = { workspace = true }
gix-object = { workspace = true }
gix-pack = { workspace = true }
gix-actor = { workspace = true }
# Full porcelain, only for the `client`-gated `mirror` module's `gix::open`.
gix = { workspace = true, optional = true }
";
/// **RED 1 — the manifest rule fires on the line that caused it.**
///
/// One dependency line in `gunnar-wire`, one finding, naming `gunnar-pack`. Not
/// "a violation somewhere in the graph": line 3 of the file somebody typed.
#[test]
fn the_manifest_rule_goes_red_on_gunnar_wires_pack_edge() {
let found = check_manifest("crates/gunnar-wire/Cargo.toml", WIRE_MANIFEST_BEFORE);
assert_eq!(
found.len(),
1,
"expected exactly the `gunnar-pack` edge, got: {found:?}"
);
assert_eq!(found[0].rule, Rule::ManifestEdge);
assert_eq!(found[0].line, 3);
assert!(
found[0].why.contains("gunnar-pack") && found[0].why.contains("dev-dependencies"),
"the failure must name the edge and where it belongs instead: {}",
found[0].why
);
}
/// **RED 2 — four of `gunnar-server`'s five gix lines fire, and `gix-hash`
/// deliberately does not.**
///
/// The residue is the point of the rule as much as the ban is: a guard that
/// also banned the value types would be a guard nobody could make green, and it
/// would be switched off rather than satisfied.
///
/// # This test moved on 2026-08-10, and the move is the record
///
/// It asserted **three** — `gunnar-pack`, `gix-pack`, `gix-actor` — and that
/// `gix-object` was among the spared. That was Z's judgement and it was
/// defensible: a decoder over bytes obtained through the contract is not a
/// reach around the contract. What changed is not the principle but the
/// arithmetic. `gix-object` is seven crates for four grammars gunnar reads and
/// never writes, `gunnar_store::object` answers the same five questions with
/// none, and the difference is checked against `gix-object` itself as an
/// outside oracle. So the fourth line fires now, under
/// [`Rule::ObjectModel`] rather than [`Rule::ManifestEdge`], because it is a
/// different argument and a failure should say which one it is making.
///
/// `gix-hash` is what is left, and it stays: replacing it is a rename across
/// nine crates plus `gunnar-bitmap` in edda, and it buys three crates rather
/// than seven.
#[test]
fn the_manifest_rule_goes_red_on_the_servers_pipeline_crates_and_spares_the_value_types() {
let found = check_manifest("crates/gunnar-server/Cargo.toml", SERVER_MANIFEST_BEFORE);
let mut hit: Vec<&str> = found
.iter()
.map(|f| {
SERVER_MANIFEST_BEFORE
.lines()
.nth(f.line - 1)
.unwrap()
.split('=')
.next()
.unwrap()
.trim()
})
.collect();
hit.sort_unstable();
assert_eq!(
hit,
vec!["gix-actor", "gix-object", "gix-pack", "gunnar-pack"],
"expected the pack pipeline, the actor parser and the object model to fire — and \
`gix-hash`, the one value type left, not to"
);
let rule_of = |dep: &str| {
found
.iter()
.find(|f| {
SERVER_MANIFEST_BEFORE
.lines()
.nth(f.line - 1)
.unwrap()
.starts_with(dep)
})
.map(|f| f.rule)
};
assert_eq!(rule_of("gunnar-pack"), Some(Rule::ManifestEdge));
assert_eq!(rule_of("gix-pack"), Some(Rule::ManifestEdge));
assert_eq!(rule_of("gix-actor"), Some(Rule::ManifestEdge));
assert_eq!(
rule_of("gix-object"),
Some(Rule::ObjectModel),
"the object edge is a cost argument, not a pipeline one, and the failure must say so"
);
}
/// **`[dev-dependencies]` is not a loophole and not a false positive.**
///
/// `gunnar-pack` as an outside oracle — the thing that indexes a pack gunnar
/// produced and disagrees when gunnar is wrong — is exactly where it
/// should be, and the rule has to be able to tell that from the edge above. If
/// this ever goes red the rule has become one nobody can satisfy.
#[test]
fn a_dev_dependency_on_gunnar_pack_is_the_correct_place_for_it() {
let manifest = "\
[dependencies]
gunnar-store = { workspace = true }
[dev-dependencies]
gunnar-pack = { workspace = true }
gix-pack = { workspace = true }
";
assert!(
check_manifest("crates/gunnar-wire/Cargo.toml", manifest).is_empty(),
"a dev-dependency never reaches a shipped artifact and must not fire"
);
}
/// **RED 3 — the source rule fires on the field that named `gix-pack`.**
///
/// `crates/gunnar-server/src/transport.rs` at `e80f175`, verbatim. Two tokens,
/// populating a receipt for a push the *engine* had already stored through
/// `GitOps::put_pack`.
#[test]
fn the_source_rule_goes_red_on_the_pack_version_field() {
let before = "\
Ok(PackReceipt {
indexed: gunnar_pack::IndexedPack {
num_objects: received.num_objects,
pack_version: match received.version {
3 => gix_pack::data::Version::V3,
_ => gix_pack::data::Version::V2,
},
";
let found = check_source("crates/gunnar-server/src/transport.rs", before);
assert_eq!(found.len(), 3, "{found:?}");
assert!(found.iter().all(|f| f.rule == Rule::PackPipeline));
assert_eq!(
found.iter().map(|f| f.line).collect::<Vec<_>>(),
vec![2, 5, 6]
);
}
/// **Prose naming the pipeline is prose.**
///
/// This module, `gunnar_wire::pack` and `xtask::engine_seam` all explain at
/// length what naming `gunnar_pack::` cost, and a guard that fired on its own
/// explanation would be switched off within a day. Comments are stripped before
/// a path is looked for — the same rule, and the same single-line `//` split,
/// as [`xtask::pack_pipeline::check_source`].
#[test]
fn a_comment_naming_the_pipeline_is_not_a_use_of_it() {
let text = "\
//! What stood here was `gunnar_pack::write_pack_copy` driving
//! `gix_pack::data::output::entry::iter_from_counts`. Both are gone.
// `gix_pack::index::File::at` collected every oid in it.
let stats = self.git.emit_pack(&selected, &vouched, &caps, &mut tapped)?;
";
assert!(
check_source("crates/gunnar-wire/src/upload_pack.rs", text).is_empty(),
"the guard must not fire on the paragraph that explains it"
);
}
/// **RED 4 — an engine named outside the adapter directory.**
///
/// `storage.rs`'s header claims it is *"the only place in gunnar that names an
/// implementation"* of the contract. Until this rule, nothing checked the
/// claim. The adapter itself must stay green — an adapter has to name the thing
/// it adapts.
#[test]
fn the_engine_rule_goes_red_off_the_adapter_and_green_on_it() {
let text = " let store = znippy_plugin_git::GitStore::open_with(&root, &account, kind)?;\n";
let leaked = check_source("crates/gunnar-server/src/transport.rs", text);
assert_eq!(leaked.len(), 1, "{leaked:?}");
assert_eq!(leaked[0].rule, Rule::EngineByName);
assert!(
check_source("crates/gunnar-server/src/storage/znippy_engine.rs", text).is_empty(),
"the adapter is the one place that may name its engine"
);
assert!(
check_source("crates/gunnar-server/src/storage/gix_engine.rs", text).is_empty(),
"and so is the other adapter"
);
}
/// **Crates outside the serving tier are not this guard's business.**
///
/// `gunnar-client` is built on gix porcelain and `gunnar-cli` links the pack
/// writer for `gunnar pack`. Both are correct. A rule that reached them would
/// be a rule about the wrong thing.
#[test]
fn the_client_half_is_out_of_scope() {
let text = " let outcome = gunnar_pack::write_pack(&plan.ids, &repo, w, &opts)?;\n";
assert!(check_source("crates/gunnar-client/src/push.rs", text).is_empty());
assert!(check_source("crates/gunnar-cli/src/pack.rs", text).is_empty());
}
/// **GREEN — and over a file count that proves something was read.**
///
/// Zero findings over zero files is shaped exactly like a clean sweep, which is
/// `xtask::guard`'s empty-graph trap in its other form. The floor is deliberate
/// and low: it asserts the scanner found the tree, not how big the tree is.
#[test]
fn the_serving_tier_is_clean_today() {
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.expect("xtask sits one level under the workspace root")
.to_path_buf();
let (findings, files) = scan(&root);
assert!(
files > 20,
"the seam scan read {files} file(s) under {root:?}; it is not reading the tree, and \
a scan that reads nothing reports clean"
);
assert!(
findings.is_empty(),
"the serving tier reaches around the contract in {} place(s):\n{}",
findings.len(),
findings
.iter()
.map(|f| format!(" {f}"))
.collect::<Vec<_>>()
.join("\n")
);
}
// ───────────────────────────────────────────────────────────────────────────
// `Rule::ObjectModel`, added 2026-08-10 with `gix-object`'s removal
// ───────────────────────────────────────────────────────────────────────────
/// `gunnar-wire/src/graph.rs` at `458281d`, verbatim from `git show`: the tag
/// peeler, one of five places the serving tier decoded with `gix-object`.
const WIRE_GRAPH_BEFORE: &str = "\
let tag = gix_object::TagRef::from_bytes(&buf, self.hash_kind)
.map_err(|err| self.corrupt(¤t, err))?;
tags.push(current);
current = tag.target();
";
/// `gunnar-policy/src/ancestry.rs` at `458281d`, verbatim. The gate's parent
/// walk, and the reason [`xtask::engine_seam::DECODER_TIER`] is wider than the
/// serving tier: `gunnar-policy` is in the appliance graph, so its manifest
/// edge cost the appliance the same seven crates that `gunnar-wire`'s did.
const POLICY_ANCESTRY_BEFORE: &str = "\
// `parent_ids` is a header scan; it never decodes the message or the
// signature, which matters because a signed commit's header is large.
let parents: Vec<ObjectId> = gix_object::CommitRefIter::from_bytes(&bytes, hash_kind)
.parent_ids()
.collect();
";
/// `gunnar-server/Cargo.toml` at `458281d`, verbatim: `gix-object` still a
/// normal dependency, `gix-hash` beside it and staying.
const SERVER_MANIFEST_WITH_OBJECT: &str = "\
[dependencies]
gunnar-grpc = { workspace = true }
gix-hash = { workspace = true }
gix-object = { workspace = true }
";
/// **RED — the source half, on the real decode it replaced.**
#[test]
fn the_object_rule_goes_red_on_the_tag_peeler_it_replaced() {
let found = check_source("crates/gunnar-wire/src/graph.rs", WIRE_GRAPH_BEFORE);
assert_eq!(
found.len(),
1,
"expected exactly the `TagRef::from_bytes` decode, got: {found:?}"
);
assert_eq!(found[0].rule, Rule::ObjectModel);
assert_eq!(found[0].line, 1);
assert!(
found[0].why.contains("gunnar_store::object"),
"the failure must name what to decode with instead: {}",
found[0].why
);
assert!(
found[0].why.contains("gix-actor") && found[0].why.contains("gix-validate"),
"and what the edge costs, or it reads as taste: {}",
found[0].why
);
}
/// **RED — and it reaches `gunnar-policy`, which is not in the serving tier.**
///
/// The comment above the offending line names `parent_ids`, not
/// `gix_object::`, so this also exercises the comment strip: two lines of
/// prose, one finding, on line 3.
#[test]
fn the_object_rule_reaches_the_policy_gate_and_the_prose_above_it_does_not_fire() {
let found = check_source(
"crates/gunnar-policy/src/ancestry.rs",
POLICY_ANCESTRY_BEFORE,
);
assert_eq!(found.len(), 1, "expected one finding, got: {found:?}");
assert_eq!(found[0].rule, Rule::ObjectModel);
assert_eq!(found[0].line, 3, "the comment lines above must not fire");
}
/// **RED — the manifest half, and `gix-hash` beside it is untouched.**
///
/// The second assertion is the one worth having. `gix-hash` is a 32-byte array
/// and two variants; banning it here would make the rule one nobody could
/// satisfy without a nine-crate rename that buys three crates back, and a rule
/// like that gets switched off rather than obeyed.
#[test]
fn the_object_manifest_rule_fires_and_spares_gix_hash() {
let found = check_manifest(
"crates/gunnar-server/Cargo.toml",
SERVER_MANIFEST_WITH_OBJECT,
);
assert_eq!(
found.len(),
1,
"expected only the `gix-object` edge: {found:?}"
);
assert_eq!(found[0].rule, Rule::ObjectModel);
assert_eq!(found[0].line, 4);
assert!(
found[0].why.contains("dev-dependencies"),
"the failure must say where the crate does belong: {}",
found[0].why
);
}
/// **A `[dev-dependencies]` edge on `gix-object` is the correct one.**
///
/// It is not tolerated, it is *wanted*: `gunnar-store/tests/object_decode.rs`
/// runs `gunnar_store::object` and `gix-object` over the same bytes and
/// compares them field by field, and `gunnar-wire`'s and `gunnar-policy`'s
/// suites build their fixture objects with it. A rule that banned the oracle
/// would leave the decoder checked against nothing but its own author.
#[test]
fn a_dev_dependency_on_gix_object_is_the_oracle_and_not_a_violation() {
let manifest = "\
[dependencies]
gix-hash = { workspace = true }
[dev-dependencies]
gix-object = { workspace = true }
";
for krate in ["gunnar-wire", "gunnar-server", "gunnar-policy"] {
assert!(
check_manifest(&format!("crates/{krate}/Cargo.toml"), manifest).is_empty(),
"{krate}: the outside oracle must survive in [dev-dependencies]"
);
}
}
/// **`gunnar-store` is out of scope, and deliberately.**
///
/// Its `gix-object` is `optional = true` behind `conformance`, which no
/// appliance build turns on, and it is a *test harness* — the suite both
/// backends run. Covering it would ban the harness to save a crate that is
/// already absent from every shipping graph.
#[test]
fn gunnar_store_keeps_its_optional_conformance_edge() {
let manifest = "\
[dependencies]
gix-object = { workspace = true, optional = true }
";
assert!(check_manifest("crates/gunnar-store/Cargo.toml", manifest).is_empty());
}
/// **And the client half still is not this guard's business.**
#[test]
fn the_client_half_may_still_decode_with_gix_object() {
let text = " let commit = gix_object::CommitRef::from_bytes(&bytes, kind)?;\n";
assert!(check_source("crates/gunnar-client/src/mirror.rs", text).is_empty());
assert!(check_source("crates/gunnar-cli/src/log.rs", text).is_empty());
assert!(check_source("crates/gunnar-store/src/conformance.rs", text).is_empty());
}
/// **A `#[cfg(test)]` module file is test code — and only while the module
/// that declares it says so.** Replaces the one named file (`testgit.rs`) the
/// scan used to skip; red-first below: the attribute comes off and the file is
/// serving tier again.
#[test]
fn a_cfg_test_module_file_is_skipped_only_while_its_declaration_is_gated() {
use xtask::engine_seam::cfg_test_gated;
let base = std::env::temp_dir().join(format!("xtask-seam-cfgtest-{}", std::process::id()));
let src = base.join("src");
std::fs::create_dir_all(src.join("twin")).unwrap();
std::fs::write(
src.join("lib.rs"),
"pub mod twin;\n/// oracle\n#[cfg(test)]\n#[cfg(test)]\nmod testgit;\nmod helper;\n",
)
.unwrap();
std::fs::write(
src.join("twin.rs"),
"pub fn f() {}\n\n#[cfg(test)]\nmod tests;\n",
)
.unwrap();
for f in ["testgit.rs", "helper.rs", "twin/tests.rs"] {
std::fs::write(src.join(f), "use gix_object::Kind;\n").unwrap();
}
assert!(
cfg_test_gated(&src.join("twin/tests.rs")),
"`#[cfg(test)] mod tests;` in twin.rs"
);
assert!(
cfg_test_gated(&src.join("testgit.rs")),
"stacked attributes in lib.rs"
);
assert!(
!cfg_test_gated(&src.join("helper.rs")),
"no #[cfg(test)] above `mod helper;`"
);
assert!(
!cfg_test_gated(&src.join("twin.rs")),
"a module gated by nothing"
);
assert!(
!cfg_test_gated(&src.join("lib.rs")),
"a crate root is never gated"
);
std::fs::write(src.join("twin.rs"), "pub fn f() {}\n\nmod tests;\n").unwrap();
assert!(
!cfg_test_gated(&src.join("twin/tests.rs")),
"the gate came off: scanned again"
);
let _ = std::fs::remove_dir_all(&base);
// And on the live tree, the two files this skip exists for.
let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR"))
.parent()
.unwrap()
.to_path_buf();
assert!(cfg_test_gated(
&root.join("crates/gunnar-server/src/testgit.rs")
));
assert!(cfg_test_gated(
&root.join("crates/gunnar-server/src/twin/tests.rs")
));
assert!(!cfg_test_gated(
&root.join("crates/gunnar-server/src/twin.rs")
));
}