crates/gunnar-front/tests/one_front_pull.rs
//! **RED-when-broken: the front runs under ONE monetize** (owner 2026-10-10 13:35Z, final:
//! exactly ONE monetize at monetize.ignalina.dk; NO estate runs or embeds one).
//!
//! What this gate holds, K3 v3 (2026-10-11):
//! - the shipped front LINKS no monetize — not the server, not its plugin host, not the
//! dial-in door — in ANY feature set ([dependencies], [build-dependencies], every feature);
//! - there is no embedded monetize SOURCE: no `src/monetize.rs` serve thread on loopback
//! :50061, no `src/self_register.rs` (the LEGACY lane monetize DIALS), no
//! `src/ledger_backup.rs` (the embedded ledger pushed off vm1);
//! - what STAYS is the pull channel only: F4's `recharge.rs` — the front calls the ONE
//! monetize IN (`SoldEstate.Recharge/Upgrade/TakeMaterial`) over `monetize-proto` and signs
//! with `monetize::sign`; those two crates are the WIRE of the pull, not a monetize.
//!
//! The parity of the thin client's words with the shop's is held by
//! `tests/shop_pairing_contract.rs` (dev-dependencies only: nothing of it ships).
use std::path::{Path, PathBuf};
const MANIFEST: &str = include_str!("../Cargo.toml");
/// The crates that ARE a per-estate monetize, or only exist to feed or dial one.
/// `monetize` (sign/verify) and `monetize-proto` (the wire) are NOT here: they are
/// how an estate calls the ONE monetize and verifies its signed orders.
const EMBEDS_A_MONETIZE: &[&str] = &[
"monetize-server",
"monetize-front",
"monetize-product-wasm",
"plugin-door-wire",
];
fn names_in(table: &toml::Table, key: &str) -> Vec<String> {
table
.get(key)
.and_then(|d| d.as_table())
.map(|d| d.keys().cloned().collect())
.unwrap_or_default()
}
#[test]
fn the_front_ships_no_embedded_monetize_in_any_build() {
let m: toml::Table = toml::from_str(MANIFEST).expect("the front's Cargo.toml");
let deps: Vec<String> = ["dependencies", "build-dependencies"]
.iter()
.flat_map(|k| names_in(&m, k))
.collect();
let linked: Vec<&String> = deps
.iter()
.filter(|d| EMBEDS_A_MONETIZE.contains(&d.as_str()))
.collect();
assert!(
linked.is_empty(),
"the front links an embedded monetize: {linked:?}"
);
let features = m
.get("features")
.and_then(|f| f.as_table())
.cloned()
.unwrap_or_default();
for (name, on) in &features {
let on: Vec<&str> = on
.as_array()
.map(|a| a.iter().filter_map(|v| v.as_str()).collect())
.unwrap_or_default();
let named: Vec<&&str> = on
.iter()
.filter(|f| {
EMBEDS_A_MONETIZE
.iter()
.any(|c| f.trim_start_matches("dep:").split('/').next() == Some(c))
})
.collect();
assert!(
named.is_empty(),
"feature `{name}` turns an embedded monetize on: {named:?}"
);
assert!(!on.iter().any(|f| f.contains("custody-ring")), "feature `{name}` turns the SHOP's custody on — that is the ONE box's, never an estate's: {on:?}");
}
}
fn src_files() -> Vec<PathBuf> {
fn walk(dir: &Path, out: &mut Vec<PathBuf>) {
for e in std::fs::read_dir(dir).expect("src/ reads").flatten() {
let p = e.path();
if p.is_dir() {
walk(&p, out);
} else if p.extension().is_some_and(|x| x == "rs") {
out.push(p);
}
}
}
let mut out = Vec::new();
walk(&Path::new(env!("CARGO_MANIFEST_DIR")).join("src"), &mut out);
out
}
#[test]
fn no_monetize_server_socket_and_no_self_register_path_are_built_here() {
let files = src_files();
for gone in ["monetize.rs", "self_register.rs", "ledger_backup.rs"] {
let still: Vec<&PathBuf> = files
.iter()
.filter(|p| p.file_name().is_some_and(|n| n == gone))
.collect();
assert!(
still.is_empty(),
"src/{gone} is an embedded monetize's (ONE monetize): {still:?}"
);
}
for p in &files {
let text = std::fs::read_to_string(p).expect("a source file reads");
for said in ["monetize_server::cli", "self_register", ":50061", "50061"] {
assert!(
!text.contains(said),
"{} still says {said:?}: an embedded monetize path (ONE monetize)",
p.display()
);
}
}
}
/// **The pull channel stays.** F4: a sold estate's front re-admits its own lost box — the
/// front CALLS the ONE monetize in; the shop never calls into an estate (G1). The metered
/// front keeps the wire (`monetize-proto`), the signature (`monetize`) and the ONE pump
/// (`gunnar-repair`); `src/recharge.rs` is F4's and survives K3.
#[test]
fn f4_recharge_and_the_pull_wire_survive_the_monetize_removal() {
let m: toml::Table = toml::from_str(MANIFEST).expect("the front's Cargo.toml");
let metered: Vec<String> = m["features"]["metered"]
.as_array()
.expect("a metered feature")
.iter()
.filter_map(|v| v.as_str().map(String::from))
.collect();
for kept in [
"dep:monetize-proto",
"dep:monetize",
"dep:gunnar-repair",
"nordisk-pairing/installer-wireguard",
] {
assert!(
metered.iter().any(|f| f == kept),
"the paid front lost the pull channel's {kept}: {metered:?}"
);
}
assert!(
Path::new(env!("CARGO_MANIFEST_DIR"))
.join("src/recharge.rs")
.is_file(),
"F4's recharge.rs is gone — the sold front can no longer re-admit its boxes"
);
assert!(!metered.iter().any(|f| f.starts_with("dep:monetize-server")), "the paid front links monetize-server: the SoldEstate client is the thin `shop_door`, not the server crate");
}