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

nordisk/monetize

crates/monetize-server/tests/pull_estate.rs

//! **G1 pull, served: a product whose estate CALLS monetize** (5.4).
//!
//! `[products.<id>] instance = "<estate>"` names the estate whose main serves the product's
//! tenants. Monetize never dials it: the registry wraps the plugin in
//! `monetize_guardian::pulled::Pulled`, which answers from the main's `Fleet.Report` and
//! queues signed orders on the guardian's store. `fleet_keys` are the boxes' keys, registered
//! at start, so the estate's first report is heard. An `instance` beside anything that dials
//! (`endpoint`, `guest_grpc_hosts`, `restoring_from_twin`) is refused at load, by name.

use monetize_embed::fleet::Report;
use monetize_embed::signing::base64_encode;
use monetize_product::factory::{ProductBuild, ProductFactory};
use monetize_product::guardian::role;
use monetize_product::pull::{order, ProductReport};
use monetize_product::*;
use monetize_server::config::Config;
use monetize_server::registry::{Linked, Registry};
use monetize_server::state::AppState;

/// The plugin under the wrapper: every verb that would dial the box panics.
struct Dialler;

impl Product for Dialler {
    fn facts(&self) -> monetize_product::ProductFacts {
        monetize_product::ProductFacts::new("gunnar", &[])
    }
    fn list_tenants(&self) -> Result<Vec<TenantId>, ProductError> {
        panic!("dialled list_tenants")
    }
    fn read_usage(&self, _: &TenantId) -> Result<Usage, ProductError> {
        panic!("dialled read_usage")
    }
    fn push_entitlement(&self, _: &EntitlementFact) -> Result<(), ProductError> {
        panic!("dialled push_entitlement")
    }
    fn can_absorb(&self, _: &TenantId, _: &std::collections::BTreeMap<String, u64>) -> Result<Absorb, String> {
        panic!("dialled can_absorb")
    }
    fn servable(&self) -> Servable {
        panic!("dialled servable")
    }
}

fn build(_: &ProductBuild<'_>) -> Result<Box<dyn Product>, String> {
    Ok(Box::new(Dialler))
}

fn no_identity(b: &ProductBuild<'_>) -> Result<String, String> {
    Err(b.err("has no identity of its own"))
}

static DIALLER: ProductFactory = ProductFactory { name: "gunnar", build, mint_identity: no_identity, guardian: None };

fn linked() -> Linked {
    let mut l = Linked::open();
    l.product(DIALLER);
    l
}

fn main_key_b64() -> String {
    base64_encode(ed25519_dalek::SigningKey::from_bytes(&[9u8; 32]).verifying_key().as_bytes())
}

fn pulled_config() -> String {
    format!("[products.gunnar]\nfree = true\ninstance = \"gunnar.rs\"\nfleet_keys = {{ main = \"{}\" }}\n", main_key_b64())
}

fn now_ms() -> u64 {
    std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_millis() as u64
}

#[test]
fn an_instance_beside_anything_that_dials_is_refused_at_load() {
    for dial in ["endpoint = \"10.0.0.1:50051\"", "guest_grpc_hosts = [\"10.0.0.2:50051\"]", "restoring_from_twin = \"10.0.0.2:50051\""] {
        let text = format!("{}{dial}\n", pulled_config());
        let e = Config::from_toml(&text).unwrap_err().to_string();
        let key = dial.split(' ').next().unwrap();
        assert!(e.contains("[products.gunnar]") && e.contains(key) && e.contains("never dials"), "{dial}: {e}");
    }
    let e = Config::from_toml("[products.gunnar]\nfree = true\ninstance = \"gunnar.rs\"\nfleet_keys = { boss = \"x\" }\n").unwrap_err().to_string();
    assert!(e.contains("fleet_keys") && e.contains("boss"), "an unknown role is refused: {e}");
}

#[test]
fn a_pulled_product_is_declared_at_start_and_answers_from_its_mains_report() {
    let cfg = Config::from_toml(&pulled_config()).expect("a pulled product loads");
    assert_eq!(cfg.products["gunnar"].instance.as_deref(), Some("gunnar.rs"));
    let reg = Registry::from_config_with(&cfg, &linked()).expect("the registry builds");
    let state = AppState::in_memory(reg);
    monetize_server::fleet::declare_pulled(&state, &cfg).expect("declared");
    let g = state.fleet.guardian().expect("the in-memory guardian");
    assert_eq!(g.store.product_of("gunnar.rs").as_deref(), Some("gunnar"));
    assert!(g.store.key_of("gunnar.rs", role::MAIN).is_some(), "the main's key is registered, so its first report is heard");

    let p = state.registry.products().find(|p| p.id() == "gunnar").expect("served");
    assert!(matches!(p.list_tenants(), Err(ProductError::Unavailable(w)) if w.contains("gunnar.rs")), "before a report: unavailable, never a dial");

    let now = now_ms();
    let pr = ProductReport {
        tenants: vec![TenantOwner { tenant: TenantId("acme".into()), person: false, seller: false }],
        usage: [("acme".to_string(), Usage { meters: [("pack_bytes".to_string(), 7)].into(), measured_at_unix_ms: now })].into(),
        measured_unix_ms: now,
        ..Default::default()
    };
    let r = Report { product: Some(serde_json::to_string(&pr).unwrap()), measured_unix_ms: now, ..Default::default() };
    g.store.record_report("gunnar.rs", role::MAIN, now, &r).unwrap();
    assert_eq!(p.list_tenants().unwrap(), vec![TenantId("acme".into())]);
    assert_eq!(p.read_usage(&TenantId("acme".into())).unwrap().meters["pack_bytes"], 7);

    let fact = EntitlementFact {
        tenant: TenantId("acme".into()),
        plan: "gunnar/10gb-1m".into(),
        state: State::Paid,
        paid_until_unix_ms: None,
        caps: Default::default(),
        source: "test".into(),
        signature: Vec::new(),
        issued_unix_ms: Some(now),
        issued_signature: Vec::new(),
    };
    p.push_entitlement(&fact).expect("queued, not dialled");
    let queued = g.store.orders_for("gunnar.rs", role::MAIN, 0);
    assert_eq!(queued.len(), 1);
    assert_eq!(queued[0].kind, order::ENTITLEMENT);
}

/// ★ **A pulled product fed AFTER start is declared live** (the ONE box's feed arrives after
/// monetize serves; no restarts): the guest watcher's look declares its estate and registers its
/// boxes' keys, so the estate's first report is heard — not only `declare_pulled` at start.
#[test]
fn a_pulled_product_fed_after_start_is_declared_by_the_watcher() {
    let dir = std::path::PathBuf::from(env!("CARGO_TARGET_TMPDIR")).join(format!("pull-live-{}", std::process::id()));
    let _ = std::fs::remove_dir_all(&dir);
    std::fs::create_dir_all(&dir).unwrap();
    let path = dir.join("monetize.toml");
    std::fs::write(&path, "").unwrap();
    let start = Config::from_toml("").unwrap();
    let state = AppState::in_memory(Registry::from_config_with(&start, &linked()).unwrap());
    let mut last = (Vec::new(), Some(start));
    let _ = monetize_server::guests::look(&state, &path, &mut last);
    let g = state.fleet.guardian().expect("the in-memory guardian");
    assert_eq!(g.store.product_of("gunnar.rs"), None, "nothing fed yet");

    std::fs::write(&path, pulled_config()).unwrap();
    let lines = monetize_server::guests::look(&state, &path, &mut last);
    assert_eq!(g.store.product_of("gunnar.rs").as_deref(), Some("gunnar"), "the fed block's estate is declared live: {lines:?}");
    assert!(g.store.key_of("gunnar.rs", role::MAIN).is_some(), "its main's key is registered, so its first report is heard");
    assert!(lines.iter().any(|l| l.contains("[products.gunnar]") && l.contains("gunnar.rs") && l.contains("DECLARED")), "the declaration is logged: {lines:?}");

    std::fs::write(&path, format!("{}\n", pulled_config())).unwrap();
    let again = monetize_server::guests::look(&state, &path, &mut last);
    assert!(!again.iter().any(|l| l.contains("DECLARED")), "an estate already declared with the same keys is not announced again: {again:?}");
    let _ = std::fs::remove_dir_all(&dir);
}

#[test]
fn a_product_without_an_instance_is_the_plugin_as_before() {
    let cfg = Config::from_toml("[products.gunnar]\nfree = true\n").unwrap();
    assert!(cfg.products["gunnar"].instance.is_none());
    let reg = Registry::from_config_with(&cfg, &linked()).unwrap();
    let p = reg.products().find(|p| p.id() == "gunnar").unwrap();
    let dialled = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| p.list_tenants()));
    assert!(dialled.is_err(), "no instance: the plugin itself answers (here, by dialling)");
}

fn signup_config(signup_extra: &str) -> String {
    format!(
        "{}[signups.gunnar]\n{signup_extra}[signups.gunnar.plans.\"gunnar/10gb-1m\"]\namount_minor = 10000\ncurrency = \"Sek\"\ncap_bytes = 10737418240\nperiod_days = 30\n",
        pulled_config()
    )
}

fn paid(username: &str) -> monetize_pay::PaidSignup {
    monetize_pay::PaidSignup {
        vendor: "mockpay".into(),
        session: format!("cs_{username}"),
        reference: "pi_1".into(),
        email: format!("{username}@example.com"),
        username: username.into(),
        product: "gunnar".into(),
        plan: "gunnar/10gb-1m".into(),
        amount: monetize_pay::Money { minor: 10_000, currency: monetize_pay::Currency::Sek },
        tax: monetize_pay::Money { minor: 0, currency: monetize_pay::Currency::Sek },
        paid_at_unix_ms: now_ms() as i64,
        customer_country: None,
    }
}

struct SignupFixture {
    state: AppState,
    sink: monetize_server::signup::Sink,
    keys: std::sync::Arc<monetize::Keyring>,
}

fn signup_fixture() -> SignupFixture {
    let cfg = Config::from_toml(&signup_config("")).expect("a pulled product's signup loads");
    let reg = Registry::from_config_with(&cfg, &linked()).unwrap();
    let state = AppState::in_memory(reg);
    monetize_server::fleet::declare_pulled(&state, &cfg).unwrap();
    let plans = monetize_server::signup::Plans::of(cfg.signup_plans(), cfg.signup_cap_meters());
    let keys = std::sync::Arc::new(monetize::Keyring::new(monetize::Signer::from_bytes(&[7u8; 32])));
    let sink = monetize_server::signup_pull::pulled_sink(&cfg, "gunnar", &state.registry.pull_slot(), &plans, keys.clone()).expect("an instance: the pull sink");
    SignupFixture { state, sink, keys }
}

fn main_reports(f: &SignupFixture, names: &[&str], acked: Vec<monetize_embed::fleet::OrderAck>) {
    let now = now_ms();
    let pr = ProductReport { names: names.iter().map(|n| n.to_string()).collect(), measured_unix_ms: now, ..Default::default() };
    let r = Report { product: Some(serde_json::to_string(&pr).unwrap()), acked, measured_unix_ms: now, ..Default::default() };
    f.state.fleet.guardian().unwrap().store.record_report("gunnar.rs", role::MAIN, now, &r).unwrap();
}

fn ack(seq: u64, ok: bool, detail: &str) -> monetize_embed::fleet::OrderAck {
    monetize_embed::fleet::OrderAck { seq, ok, detail: detail.into(), receipt_json: String::new() }
}

fn queued(f: &SignupFixture) -> Vec<monetize_embed::fleet::SignedOrder> {
    f.state.fleet.guardian().unwrap().store.orders_for("gunnar.rs", role::MAIN, 0)
}

#[test]
fn a_pulled_products_signup_makes_the_account_over_orders_then_queues_its_entitlement() {
    use monetize_pay::{NameVerdict, SignupError, SignupOutcome};
    let f = signup_fixture();
    assert!(f.sink.creates_accounts());
    assert!(matches!(f.sink.name_verdict("bob"), Err(SignupError::Unavailable(_))), "no report yet: unknown, never free");
    main_reports(&f, &["alice"], vec![]);
    assert!(matches!(f.sink.name_verdict("alice"), Ok(NameVerdict::Taken(_))));
    assert_eq!(f.sink.name_verdict("bob"), Ok(NameVerdict::Free));

    let bob = paid("bob");
    match f.sink.paid(&bob) {
        Err(SignupError::Unavailable(w)) => assert!(w.contains("queued"), "{w}"),
        other => panic!("pending until the main acks: {other:?}"),
    }
    let q = queued(&f);
    assert_eq!(q.len(), 1, "the account only; no entitlement before the name is the buyer's: {q:?}");
    assert_eq!(q[0].kind, order::ADD_PRINCIPAL);
    let ap: monetize_product::pull::AddPrincipal = serde_json::from_str(&q[0].body).unwrap();
    assert_eq!((ap.username.as_str(), ap.signup.as_str()), ("bob", "mockpay:cs_bob"));
    assert!(matches!(f.sink.name_verdict("bob"), Ok(NameVerdict::Taken(_))), "a paid signup is making it");

    main_reports(&f, &["alice", "bob"], vec![ack(q[0].seq, true, "bob")]);
    assert_eq!(f.sink.paid(&bob), Ok(SignupOutcome::Created { namespace: "bob".into(), username: "bob".into() }));
    let q = queued(&f);
    assert_eq!(q.len(), 1, "{q:?}");
    assert_eq!(q[0].kind, order::ENTITLEMENT);
    let fact: EntitlementFact = serde_json::from_str(&q[0].body).unwrap();
    assert_eq!(fact.tenant, TenantId("bob".into()));
    assert_eq!(fact.caps.get("pack_bytes"), Some(&10_737_418_240));
    assert!(monetize::verify_fact(&fact, &f.keys.product("gunnar").verifying_key()).is_ok(), "signed by monetize's GUNNAR key (G8)");
    assert!(monetize::verify_fact(&fact, &monetize::Signer::from_bytes(&[7u8; 32]).verifying_key()).is_err(), "never by the root key");
}

#[test]
fn a_name_the_main_says_is_taken_is_name_taken_and_no_entitlement_leaves() {
    use monetize_pay::SignupError;
    let f = signup_fixture();
    main_reports(&f, &[], vec![]);
    let bob = paid("bob");
    assert!(f.sink.paid(&bob).is_err());
    let seq = queued(&f)[0].seq;
    main_reports(&f, &["bob"], vec![ack(seq, false, "taken: bob is somebody else's")]);
    assert!(matches!(f.sink.paid(&bob), Err(SignupError::NameTaken(w)) if w.contains("bob")));
    assert!(queued(&f).is_empty());
    assert!(matches!(f.sink.paid(&paid("X")), Err(SignupError::NameTaken(_))), "a name that is not a name is refused before any order");
    assert!(queued(&f).is_empty());
}

#[test]
fn a_product_without_an_instance_keeps_its_own_sink_and_a_pulled_one_takes_no_guest() {
    let cfg = Config::from_toml("[products.gunnar]\nfree = true\n[signups.gunnar]\n").unwrap();
    let reg = Registry::from_config_with(&cfg, &linked()).unwrap();
    let plans = monetize_server::signup::Plans::of(cfg.signup_plans(), cfg.signup_cap_meters());
    let keys = std::sync::Arc::new(monetize::Keyring::new(monetize::Signer::from_bytes(&[7u8; 32])));
    assert!(monetize_server::signup_pull::pulled_sink(&cfg, "gunnar", &reg.pull_slot(), &plans, keys).is_none());
    let e = Config::from_toml(&signup_config("guest = \"/nowhere/gunnar.wasm\"\n")).unwrap_err().to_string();
    assert!(e.contains("[signups.gunnar]") && e.contains("guest") && e.contains("instance"), "{e}");
}

/// The attached estate of the same product on the ONE box (owner 2026-10-11: gunnar.rs and
/// test2.gunnar.rs, both gunnar): joined, so the fleet knows it as a gunnar estate.
const TEST2: &str = "test2-gunnar-rs";

fn test2_reports(f: &SignupFixture, names: &[&str], acked: Vec<monetize_embed::fleet::OrderAck>) {
    let now = now_ms();
    let pr = ProductReport { names: names.iter().map(|n| n.to_string()).collect(), measured_unix_ms: now, ..Default::default() };
    let r = Report { product: Some(serde_json::to_string(&pr).unwrap()), acked, measured_unix_ms: now, ..Default::default() };
    f.state.fleet.guardian().unwrap().store.record_report(TEST2, role::MAIN, now, &r).unwrap();
}

fn queued_on(f: &SignupFixture, estate: &str) -> Vec<monetize_embed::fleet::SignedOrder> {
    f.state.fleet.guardian().unwrap().store.orders_for(estate, role::MAIN, 0)
}

/// ★ **A signup from an attached estate makes its account on THAT estate's main** (ONE box,
/// two sites of gunnar, owner 2026-10-11): the `add_principal` and, once acked, the signed
/// entitlement are queued for `(gunnar, test2-gunnar-rs, main)` — never the product's home
/// estate. The name is checked against test2's main, and the tenant monetize keys is
/// `@test2-gunnar-rs/<name>`, while test2's main is handed its own plain name.
#[test]
fn a_signup_from_an_attached_estate_makes_its_account_on_that_estates_main() {
    use monetize_pay::{NameVerdict, SignupError, SignupOutcome};
    let f = signup_fixture();
    f.state.fleet.guardian().unwrap().store.declare(TEST2, "gunnar").unwrap();
    main_reports(&f, &["carol"], vec![]);
    test2_reports(&f, &["dave"], vec![]);
    assert_eq!(f.sink.name_verdict_on("gunnar", "carol", Some(TEST2)), Ok(NameVerdict::Free), "carol is gunnar.rs's, not test2's");
    assert!(matches!(f.sink.name_verdict_on("gunnar", "dave", Some(TEST2)), Ok(NameVerdict::Taken(_))), "dave is test2's");
    assert!(matches!(f.sink.name_verdict_on("gunnar", "carol", None), Ok(NameVerdict::Taken(_))), "no estate: the home's, as before");

    let bob = paid("bob");
    match f.sink.paid_on(&bob, Some(TEST2)) {
        Err(SignupError::Unavailable(w)) => assert!(w.contains("queued") && w.contains(TEST2), "{w}"),
        other => panic!("pending until test2's main acks: {other:?}"),
    }
    assert!(queued(&f).is_empty(), "nothing for the home estate's main: {:?}", queued(&f));
    let q = queued_on(&f, TEST2);
    assert_eq!(q.len(), 1, "{q:?}");
    assert_eq!((q[0].kind.as_str(), q[0].product.as_str(), q[0].instance.as_str(), q[0].role.as_str()), (order::ADD_PRINCIPAL, "gunnar", TEST2, role::MAIN));
    let ap: monetize_product::pull::AddPrincipal = serde_json::from_str(&q[0].body).unwrap();
    assert_eq!(ap.username, "bob", "test2's main is asked for its own plain name");
    assert!(matches!(f.sink.name_verdict_on("gunnar", "bob", Some(TEST2)), Ok(NameVerdict::Taken(_))), "a paid signup is making it on test2");

    test2_reports(&f, &["dave", "bob"], vec![ack(q[0].seq, true, "bob")]);
    assert_eq!(f.sink.paid_on(&bob, Some(TEST2)), Ok(SignupOutcome::Created { namespace: format!("@{TEST2}/bob"), username: "bob".into() }), "monetize keys test2's tenant by its estate");
    assert!(queued(&f).is_empty(), "still nothing for the home estate: {:?}", queued(&f));
    let q = queued_on(&f, TEST2);
    assert_eq!(q.len(), 1, "{q:?}");
    assert_eq!(q[0].kind, order::ENTITLEMENT);
    let fact: EntitlementFact = serde_json::from_str(&q[0].body).unwrap();
    assert_eq!(fact.tenant, TenantId("bob".into()), "test2's main holds its own name");
    // Re-signed for test2's own name by the guardian, with monetize's GUNNAR key (G8) — the
    // keyring the guardian shares with the server (one keyring on a real box).
    assert!(monetize::verify_fact(&fact, &f.state.keys.product("gunnar").verifying_key()).is_ok(), "signed by monetize's GUNNAR key (G8)");

    // The home estate named as the estate is the home, as before; an estate the fleet does
    // not know for gunnar makes nothing anywhere.
    assert!(f.sink.paid_on(&paid("erik"), Some("gunnar.rs")).is_err());
    assert_eq!(queued(&f).len(), 1, "the home's own signup is the home's");
    assert!(matches!(f.sink.paid_on(&paid("fia"), Some("nowhere-rs")), Err(SignupError::Refused(w)) if w.contains("nowhere-rs")));
    assert!(queued_on(&f, "nowhere-rs").is_empty());
}

/// ★ **A webhook's signup is sited by the account its money went through**: each site bills
/// through its own vendor instance (`[estates.<estate>] vendor`), so that instance names the
/// estate the account is made on. A vendor no estate bills through names none (the home).
#[test]
fn a_signups_estate_is_the_one_whose_account_took_the_money() {
    let reg = Registry::new()
        .estate(TEST2, monetize_server::config::EstateConfig { product: "gunnar".into(), vendor: "stripe/gunnar-test2".into(), ..Default::default() })
        .estate("gunnar-rs", monetize_server::config::EstateConfig { product: "gunnar".into(), vendor: "stripe/gunnar".into(), ..Default::default() });
    assert_eq!(reg.estate_of_vendor("gunnar", "stripe/gunnar-test2").as_deref(), Some(TEST2));
    assert_eq!(reg.estate_of_vendor("gunnar", "stripe/gunnar").as_deref(), Some("gunnar-rs"));
    assert_eq!(reg.estate_of_vendor("holger", "stripe/gunnar-test2"), None, "another product's site is not this one's");
    assert_eq!(reg.estate_of_vendor("gunnar", "mockpay"), None);
}

/// ★ UW-4 (owner: the customer never sees a cap): **past the room of an attached estate whose
/// set grows at runtime, an order is SOLD and QUEUED** — served from the box once it grows —
/// and the estate is told by ONE signed `grow_room` order, the operator by a line. A sealed
/// set is refused as before.
#[test]
fn past_the_room_of_an_attached_estate_an_order_is_sold_queued_and_the_estate_told() {
    let cfg = Config::from_toml(&pulled_config()).expect("a pulled product loads");
    let reg = Registry::from_config_with(&cfg, &linked()).expect("the registry builds");
    let state = AppState::in_memory(reg);
    monetize_server::fleet::declare_pulled(&state, &cfg).expect("declared");
    let g = state.fleet.guardian().expect("the in-memory guardian");
    let p = state.registry.products().find(|p| p.id() == "gunnar").expect("served");
    const GIB: u64 = 1 << 30;
    let report = |growth: Growth| {
        let now = now_ms();
        let pr = ProductReport {
            servable: Some(Servable::Measured { servable_bytes: 10 * GIB, total_bytes: 100 * GIB, growth, ceilings: Default::default() }),
            room: [("pack_bytes".to_string(), 10 * GIB)].into(),
            measured_unix_ms: now,
            ..Default::default()
        };
        let r = Report { product: Some(serde_json::to_string(&pr).unwrap()), measured_unix_ms: now, ..Default::default() };
        g.store.record_report("gunnar.rs", role::MAIN, now, &r).unwrap();
    };
    let acme = TenantId("acme".into());
    let caps: std::collections::BTreeMap<String, u64> = [("pack_bytes".to_string(), 30 * GIB)].into();

    report(Growth::Sealed("laid once".into()));
    assert!(monetize_server::grow::can_absorb_growing(&state, p, &acme, &caps).is_err(), "a sealed set: refused, as before");
    assert_eq!(monetize_server::grow::queue_past_room(&state, p, &acme, &caps), None);
    assert!(g.store.orders_for("gunnar.rs", role::MAIN, 0).is_empty());

    report(Growth::AtRuntime("grows in place".into()));
    assert!(matches!(monetize_server::grow::can_absorb_growing(&state, p, &acme, &caps), Ok(Absorb::OnHand)), "sold, served once the set grows");
    let line = monetize_server::grow::queue_past_room(&state, p, &acme, &caps).expect("the operator is told");
    assert!(line.contains("acme") && line.contains("queued"), "{line}");
    let q = g.store.orders_for("gunnar.rs", role::MAIN, 0);
    assert_eq!(q.len(), 1, "{q:?}");
    assert_eq!(q[0].kind, order::GROW_ROOM);
    let body: monetize_product::pull::GrowRoom = serde_json::from_str(&q[0].body).unwrap();
    assert_eq!(body.need_bytes, 30 * GIB);
}

/// A Holger-shaped plugin under the wrapper: its sold meter is `disk_bytes` (a disk-backed
/// meter, never Gunnar's `pack_bytes`); every verb that would dial panics.
struct HolgerDialler;

const HOLGER_METERS: &[Meter] = &[Meter::new("disk_bytes", "what a repository occupies on disk", Enforcement::Enforced).with_backing(Backing::DiskBytes)];

impl Product for HolgerDialler {
    fn facts(&self) -> monetize_product::ProductFacts {
        monetize_product::ProductFacts::new("holger", HOLGER_METERS)
    }
    fn list_tenants(&self) -> Result<Vec<TenantId>, ProductError> {
        panic!("dialled list_tenants")
    }
    fn read_usage(&self, _: &TenantId) -> Result<Usage, ProductError> {
        panic!("dialled read_usage")
    }
    fn push_entitlement(&self, _: &EntitlementFact) -> Result<(), ProductError> {
        panic!("dialled push_entitlement")
    }
    fn can_absorb(&self, _: &TenantId, _: &std::collections::BTreeMap<String, u64>) -> Result<Absorb, String> {
        panic!("dialled can_absorb")
    }
    fn servable(&self) -> Servable {
        panic!("dialled servable")
    }
}

fn build_holger(_: &ProductBuild<'_>) -> Result<Box<dyn Product>, String> {
    Ok(Box::new(HolgerDialler))
}

static HOLGER_DIALLER: ProductFactory = ProductFactory { name: "holger", build: build_holger, mint_identity: no_identity, guardian: None };

/// ★ **P2 follow-up (2026-10-21; owner: the customer never sees a cap): past the room of a
/// Holger main, an order is SOLD and QUEUED, never refused.** Holger's B7 end-to-end test met
/// `/kop` 409 "disk_bytes needs 10737418240 beyond the 0 the main has room for" on a host whose
/// disk was full: the queue counted only Gunnar's `pack_bytes` + `lfs_bytes`, so a `disk_bytes`
/// order demanded nothing and was refused; and a main that cannot tell whether its set grows
/// (`Growth::Unknown`) queued nothing. Now the demand is every disk-backed meter the product
/// sells, and a main that is not SEALED is told by a `grow_room` order. A sealed set is
/// refused as before.
#[test]
fn past_the_room_of_a_holger_main_a_disk_bytes_order_is_sold_and_queued() {
    let text = format!("[products.holger]\nfree = true\ninstance = \"test3-holger-rs\"\nfleet_keys = {{ main = \"{}\" }}\n", main_key_b64());
    let cfg = Config::from_toml(&text).expect("a pulled product loads");
    let mut l = Linked::open();
    l.product(HOLGER_DIALLER);
    let state = AppState::in_memory(Registry::from_config_with(&cfg, &l).expect("the registry builds"));
    monetize_server::fleet::declare_pulled(&state, &cfg).expect("declared");
    let g = state.fleet.guardian().expect("the in-memory guardian");
    let p = state.registry.products().find(|p| p.id() == "holger").expect("served");
    const GIB: u64 = 1 << 30;
    let report = |growth: Growth| {
        let now = now_ms();
        let pr = ProductReport {
            servable: Some(Servable::Measured { servable_bytes: 0, total_bytes: 100 * GIB, growth, ceilings: Default::default() }),
            room: [("disk_bytes".to_string(), 0)].into(),
            measured_unix_ms: now,
            ..Default::default()
        };
        let r = Report { product: Some(serde_json::to_string(&pr).unwrap()), measured_unix_ms: now, ..Default::default() };
        g.store.record_report("test3-holger-rs", role::MAIN, now, &r).unwrap();
    };
    let crates = TenantId("crates".into());
    let caps: std::collections::BTreeMap<String, u64> = [("disk_bytes".to_string(), 10 * GIB)].into();

    report(Growth::Sealed("laid once".into()));
    assert!(monetize_server::grow::can_absorb_growing(&state, p, &crates, &caps).is_err(), "a sealed set: refused, as before");

    for growth in [Growth::Unknown("no hotplug seen".into()), Growth::AtRuntime("grows in place".into())] {
        report(growth.clone());
        assert!(matches!(monetize_server::grow::can_absorb_growing(&state, p, &crates, &caps), Ok(Absorb::OnHand)), "{growth:?}: sold, served once the set grows");
        let line = monetize_server::grow::queue_past_room(&state, p, &crates, &caps).unwrap_or_else(|| panic!("{growth:?}: the operator is told"));
        assert!(line.contains("crates") && line.contains("queued") && line.contains("10"), "{line}");
        let q = g.store.orders_for("test3-holger-rs", role::MAIN, 0);
        assert_eq!(q.len(), 1, "one want, the newest: {q:?}");
        let body: monetize_product::pull::GrowRoom = serde_json::from_str(&q[0].body).unwrap();
        assert_eq!(body.need_bytes, 10 * GIB, "{growth:?}: the disk_bytes the order sold past the room");
    }
}

/// ★ **i54a A2 / turn runs 4 + 8 (2026-10-12): the paid room follows the main's ack AT ONCE.**
/// A paid signup on a pulled product queues the account; the main makes it and acks in its next
/// report — and the plan's entitlement was queued only when something settled the signup
/// again: the welcome page's poll or the poller's tick (5 min). The kit's functest waited 180 s
/// and saw the account without its room (2 runs of 3). The report that carries the ack settles
/// the pending signups at once, so the entitlement is queued for the main's open long-poll.
#[test]
fn the_mains_ack_of_a_paid_account_queues_its_room_at_once_not_at_the_next_tick() {
    let mut f = signup_fixture();
    let plans = monetize_server::signup::Plans::of(Config::from_toml(&signup_config("")).unwrap().signup_plans(), Default::default());
    f.state.signup_plans = plans;
    f.state.signup_sink = monetize_server::signup::HotSink::per_product(std::collections::BTreeMap::from([("gunnar".to_string(), f.sink.clone())]));
    main_reports(&f, &["alice"], vec![]);
    let bob = paid("bob");
    // the webhook: kept pending, the account queued for the main
    f.state.signups.record_pending(&bob, now_ms() as i64).unwrap();
    assert!(monetize_server::signup::settle(&f.state, &bob).is_pending());
    let q = queued(&f);
    assert_eq!((q.len(), q[0].kind.as_str()), (1, order::ADD_PRINCIPAL), "{q:?}");
    // the main makes bob and acks it in its report; the server's answer to that report:
    main_reports(&f, &["alice", "bob"], vec![ack(q[0].seq, true, "bob")]);
    let settled = monetize_server::fleet::after_report(&f.state, &[q[0].seq]);
    assert_eq!(settled, 1, "the ack settled the paid signup without the poller");
    let q = queued(&f);
    assert!(q.iter().any(|o| o.kind == order::ENTITLEMENT), "bob's room is queued for the main's long-poll at once: {q:?}");
    assert!(!f.state.signups.get("mockpay", "cs_bob").unwrap().unwrap().state.is_pending());
    assert_eq!(monetize_server::fleet::after_report(&f.state, &[]), 0, "a report that acked nothing settles nothing");
}

/// The paid signup `bob`, recorded and settled once on the pulled product (the webhook): the
/// account queued for the main, which has not called yet.
fn settling_bob() -> (SignupFixture, monetize_pay::PaidSignup) {
    let mut f = signup_fixture();
    f.state.signup_plans = monetize_server::signup::Plans::of(Config::from_toml(&signup_config("")).unwrap().signup_plans(), Default::default());
    f.state.signup_sink = monetize_server::signup::HotSink::per_product(std::collections::BTreeMap::from([("gunnar".to_string(), f.sink.clone())]));
    main_reports(&f, &["alice"], vec![]);
    let bob = paid("bob");
    f.state.signups.record_pending(&bob, now_ms() as i64).unwrap();
    assert!(monetize_server::signup::settle(&f.state, &bob).is_pending(), "queued for the main: pending");
    (f, bob)
}

/// The sentence `Signup.Status` shows the buyer for `bob` now.
fn bobs_words(f: &SignupFixture) -> String {
    let rec = f.state.signups.get("mockpay", "cs_bob").unwrap().unwrap();
    monetize_server::signup::customer_words(&f.state.signups, &rec, f.state.now() as i64).0
}

/// ★ **PAID-WORDS (owner's real-card test, test2.gunnar.rs 2026-10-26 ~17:40Z): a paid account
/// waiting a few seconds for its main reads "Setting up your account", never maintenance.** The
/// box was up; the account was queued for the estate's main, as every pulled product's is, and
/// the page said "The shop is temporarily down for maintenance". Then the main acks: ready.
#[test]
fn a_paid_account_waiting_for_its_main_reads_setting_up_never_maintenance() {
    let (f, bob) = settling_bob();
    let said = bobs_words(&f);
    assert!(!said.to_lowercase().contains("maintenance"), "a normal settle said maintenance: {said:?}");
    assert_eq!(said, "Payment received. Setting up your account; this takes a few seconds.");
    let q = queued(&f);
    main_reports(&f, &["alice", "bob"], vec![ack(q[0].seq, true, "bob")]);
    assert!(!monetize_server::signup::settle(&f.state, &bob).is_pending());
    assert_eq!(bobs_words(&f), monetize_server::signup::words::READY);
}

/// ★ **The fake ONE box every site's tests stand on says what this box says** while a paid
/// account settles, and while the product says it is in maintenance (monetize-site-buy
/// `testkit`): the sites' browser tests read the box's own sentences.
#[test]
fn the_fake_box_says_what_the_box_says_while_an_account_settles() {
    let (f, _) = settling_bob();
    assert_eq!(bobs_words(&f), monetize_site_buy::testkit::SETTLING_WORDS);
    assert_eq!(monetize_server::signup::words::MAINTENANCE, monetize_site_buy::testkit::MAINTENANCE_WORDS);
    // RA4-19: the fake box's sentence for its silence, and when it is due, are the box's own.
    assert_eq!(monetize_server::signup::words::TAKING_LONGER_MAILED, monetize_site_buy::testkit::LONGER_WORDS);
    assert_eq!(monetize_server::signup::SETTLE_BOUND_MS, monetize_site_buy::testkit::SILENT_AFTER_MS);
}