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

nordisk/gunnar

crates/gunnar-server/tests/entitlement.rs

//! **The metered appliance, red first.** `Entitlement.Set` verifies, logs,
//! stores and swaps; `authorise_service` refuses a lapsed tenant's push before
//! the bytes and never their clone. Every refusal below has its allow twin in
//! the same test (measure, never assert: a gate that always allows is invisible to a test that
//! only pushes valid work), and every fact is signed with a real Ed25519 key
//! over `monetize_embed::signing::fact_message` — the ONE canonical form — so
//! nothing here is verified against a stand-in.
//!
//! Built only with `--features metered` (`required-features` in Cargo.toml):
//! without the feature the types this file names do not exist, which is the
//! doctrine and not a gap.

use std::collections::BTreeMap;
use std::sync::Arc;

use ed25519_dalek::{Signer, SigningKey};
use gunnar_common::monetize_key::MonetizePubkey;
use gunnar_core::{
    EntitlementState, Level, NewRepo, Principal, PrincipalKind, RepoRef, Visibility,
};
use gunnar_grpc::{ControlError, ControlPlane as _};
use gunnar_proto::{EntitlementFact, EntitlementState as PbState};
use gunnar_server::attest::AttestationLog;
use gunnar_server::control_plane::CoreControlPlane;
use gunnar_server::entitlement::{EntitlementSlot, MeteredConfig};
use gunnar_server::stores::ServerStores;
use gunnar_ssh::command::{GitService, Operation};
use gunnar_ssh::server::{Dispatch, DispatchError};
use gunnar_ssh::PlanGate;
use monetize_embed::{State, TenantId};

const OCT_1_2026: u64 = 1_790_812_800_000;
const BILLING: &str = "https://gunnar.rs/billing/{tenant}";

/// The issue time [`Rig::signed`] stamps unless a test says otherwise. Fixed,
/// so a test that wants two facts in a known order names the offsets itself
/// rather than racing the wall clock.
const ISSUED_AT: u64 = 1_789_000_000_000;

/// The explode budget of a namespace the door refuses — `entitlement.rs`'s
/// `NO_CACHE_BUDGET_BYTES`, spelled again here on purpose. It is private to
/// the server crate, and a test that imported it could not catch the one
/// mistake that matters: `0`, which every layer of this appliance reads as
/// UNLIMITED. This copy fails if the server's ever becomes that.
const NO_CACHE: u64 = 1;

/// **The read cache's disk line**, znippy `exploded_cache::DISK_LINE_PERCENT`:
/// a store on a filesystem this full refuses every write-back into its lazy
/// pool (the engine's own tests hold that; `git_ops`
/// `a_push_past_the_disk_line_evicts_the_oldest_cache_without_a_read`).
const DISK_LINE_PERCENT: u64 = 80;

/// How full the filesystem holding `dir` is, read the way the cache reads it:
/// `statvfs` used / (used + available to an unprivileged writer), as `df`.
fn disk_used_percent(dir: &std::path::Path) -> Option<u64> {
    let s = rustix::fs::statvfs(dir).ok()?;
    let used = s.f_blocks.saturating_sub(s.f_bfree);
    let seen = used + s.f_bavail;
    (seen > 0).then(|| used * 100 / seen)
}

struct Rig {
    _dir: tempfile::TempDir,
    stores: Arc<ServerStores>,
    key: SigningKey,
    forger: SigningKey,
    config: MeteredConfig,
    /// How many facts this rig has minted — monetize's clock, stood in for.
    minted: std::sync::atomic::AtomicU64,
}

impl Rig {
    fn new() -> Rig {
        Rig::in_dir(tempfile::tempdir().expect("tempdir"))
    }

    /// **A rig whose store the read cache may fill**: in TMPDIR when its
    /// filesystem is under the disk line, else in `/dev/shm` (Linux tmpfs) when
    /// that is; the host's own fullness is not what a cache test measures. A
    /// host with neither is said by the test's own assertion, by name.
    fn under_the_disk_line() -> Rig {
        let tmp = std::env::temp_dir();
        let shm = std::path::Path::new("/dev/shm");
        let under = |dir: &std::path::Path| {
            disk_used_percent(dir).is_some_and(|used| used < DISK_LINE_PERCENT)
        };
        let dir = if !under(&tmp) && under(shm) {
            tempfile::tempdir_in(shm).expect("tempdir in /dev/shm")
        } else {
            tempfile::tempdir().expect("tempdir")
        };
        Rig::in_dir(dir)
    }

    fn in_dir(dir: tempfile::TempDir) -> Rig {
        let stores = Arc::new(ServerStores::open(dir.path()).expect("stores"));
        let key = SigningKey::from_bytes(&[7u8; 32]);
        let forger = SigningKey::from_bytes(&[9u8; 32]);
        let pubkey = dir.path().join("monetize.pub");
        std::fs::write(&pubkey, key.verifying_key().to_bytes()).expect("write key");
        let config =
            MeteredConfig::load(&MonetizePubkey::Path(pubkey), Some(BILLING)).expect("config");
        Rig {
            _dir: dir,
            stores,
            key,
            forger,
            config,
            minted: std::sync::atomic::AtomicU64::new(0),
        }
    }

    fn slot(&self) -> Arc<EntitlementSlot> {
        EntitlementSlot::open(Arc::clone(&self.stores), &self.config).expect("slot")
    }

    fn plane(&self, slot: &Arc<EntitlementSlot>) -> CoreControlPlane {
        CoreControlPlane::new(Arc::clone(&self.stores)).with_entitlement(Arc::clone(slot))
    }

    fn dispatch(&self, slot: &Arc<EntitlementSlot>) -> Dispatch {
        Dispatch::new(
            self.stores
                .ssh_control()
                .with_plan_gate(Arc::clone(slot) as Arc<dyn PlanGate>),
        )
    }

    /// The owner of `ns`: a principal whose id IS the namespace (rule 2 of
    /// `AuthTable::may`), with the namespace and one PUBLIC repository.
    fn tenant(&self, ns: &str) -> Principal {
        let owner = Principal {
            id: ns.to_owned(),
            name: ns.to_owned(),
            kind: PrincipalKind::User,
            created: 0,
        };
        self.stores
            .auth()
            .add_principal(owner.clone())
            .expect("principal");
        self.stores
            .catalog()
            .create_namespace(ns)
            .expect("namespace");
        let path = RepoRef::new(ns, "proj").expect("legal");
        self.stores
            .create_repo(NewRepo::new(path.clone()), false)
            .expect("repo");
        self.stores
            .catalog()
            .set_visibility(&path, Visibility::Public)
            .expect("public");
        owner
    }

    /// A fact stamped with the moment monetize issued it — what
    /// `monetize::Signer::sign_fact` mints now.
    ///
    /// **Every call stamps LATER than the last**, because that is what a clock
    /// does and what every test here already assumes when it pushes a tenant up
    /// and down the ladder. A rig that stamped them all the same would make the
    /// second push of any test a replay, which is true of the wire and false of
    /// monetize.
    fn signed(
        &self,
        key: &SigningKey,
        ns: &str,
        state: State,
        caps: &[(&str, u64)],
    ) -> EntitlementFact {
        let issued = ISSUED_AT
            + self
                .minted
                .fetch_add(1, std::sync::atomic::Ordering::Relaxed);
        self.signed_at(key, ns, state, caps, Some(issued))
    }

    /// [`Rig::signed`] with the issue time chosen. `None` is the OLD form — a
    /// fact signed before the stamp existed, V1 signature only — which gunnar
    /// refuses.
    fn signed_at(
        &self,
        key: &SigningKey,
        ns: &str,
        state: State,
        caps: &[(&str, u64)],
        issued: Option<u64>,
    ) -> EntitlementFact {
        let mut fact = monetize_embed::EntitlementFact {
            tenant: TenantId(ns.to_owned()),
            plan: "10gb".into(),
            state,
            paid_until_unix_ms: Some(OCT_1_2026),
            caps: caps
                .iter()
                .map(|(k, v)| (k.to_string(), *v))
                .collect::<BTreeMap<_, _>>(),
            source: "payment:invoice:ocr-42".into(),
            signature: vec![],
            issued_unix_ms: issued,
            issued_signature: vec![],
        };
        fact.signature = key
            .sign(&monetize_embed::signing::fact_message(&fact))
            .to_bytes()
            .to_vec();
        if issued.is_some() {
            fact.issued_signature = key
                .sign(&monetize_embed::signing::fact_message_issued(&fact))
                .to_bytes()
                .to_vec();
        }
        EntitlementFact {
            namespace: fact.tenant.0,
            plan: fact.plan,
            state: match state {
                State::Free => PbState::Free,
                State::Paid => PbState::Paid,
                State::Grace => PbState::Grace,
                State::Suspended => PbState::Suspended,
                State::Retention => PbState::Retention,
            } as i32,
            paid_until_unix_ms: fact.paid_until_unix_ms,
            caps: fact.caps,
            source: fact.source,
            signature: fact.signature,
            issued_unix_ms: fact.issued_unix_ms,
            issued_signature: fact.issued_signature,
        }
    }

    fn log_lines(&self) -> Vec<String> {
        std::fs::read_to_string(self.stores.root().join(gunnar_server::ATTESTATION_LOG))
            .map(|t| t.lines().map(str::to_owned).collect())
            .unwrap_or_default()
    }
}

fn repo(ns: &str) -> RepoRef {
    RepoRef::new(ns, "proj").expect("legal")
}

// ───────────────────────────────────────────────────────────────────────────
// Step 2: Set verifies, logs, stores, swaps
// ───────────────────────────────────────────────────────────────────────────

#[test]
fn a_forged_fact_is_refused_by_name_and_nothing_moves() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("team");

    let forged = rig.signed(&rig.forger, "team", State::Paid, &[]);
    let err = plane
        .entitlement_set(forged)
        .expect_err("a signature the monetize key did not make must be refused");
    assert!(
        matches!(err, ControlError::PermissionDenied(_)),
        "a forged fact is PERMISSION_DENIED, not a stored fact: {err:?}"
    );
    assert!(
        err.to_string().contains("does not verify") && err.to_string().contains("team"),
        "the refusal names the reason and the tenant: {err}"
    );
    // NOTHING moved: not the log, not the document, not the snapshot.
    assert!(
        rig.log_lines().is_empty(),
        "a refused fact must not be logged as accepted: {:?}",
        rig.log_lines()
    );
    assert_eq!(plane.entitlement_get("team").unwrap(), None);
    assert!(plane.entitlement_list().unwrap().is_empty());
    assert_eq!(slot.counts().paid, 0);

    // A fact edited AFTER signing is a forgery too, even under the right key.
    let mut edited = rig.signed(&rig.key, "team", State::Paid, &[]);
    edited.state = PbState::Suspended as i32;
    let err = plane
        .entitlement_set(edited)
        .expect_err("edited after signing");
    assert!(matches!(err, ControlError::PermissionDenied(_)), "{err:?}");
    assert!(rig.log_lines().is_empty());

    // The allow twin: the same fact under the real key is accepted, logged
    // ONCE, and enforced.
    let (state, seq) = plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
        .expect("a genuine fact is accepted");
    assert_eq!(state, PbState::Paid);
    assert_eq!(seq, 0, "the first line of an empty log is sequence 0");
    let lines = rig.log_lines();
    assert_eq!(lines.len(), 1, "exactly one attestation line: {lines:?}");
    assert!(
        lines[0].contains("\"entitlement\"")
            && lines[0].contains("\"tenant\":\"team\"")
            && lines[0].contains("\"source\":\"payment:invoice:ocr-42\"")
            && lines[0].contains("\"state\":\"Paid\""),
        "the line carries the fact as monetize signed it: {}",
        lines[0]
    );
    assert_eq!(
        plane.entitlement_get("team").unwrap().map(|f| f.state),
        Some(PbState::Paid as i32)
    );
    assert_eq!(slot.counts().paid, 1);
    // …and a push line beside it still reads as a push log: the entitlement
    // line is skipped, not choked on.
    let log = AttestationLog::under(rig.stores.root());
    assert!(log.read().expect("the push log still parses").is_empty());
}

#[test]
fn an_accepted_fact_survives_a_reload_and_a_tampered_document_does_not() {
    let rig = Rig::new();
    rig.tenant("team");
    {
        let slot = rig.slot();
        let plane = rig.plane(&slot);
        plane
            .entitlement_set(rig.signed(
                &rig.key,
                "team",
                State::Suspended,
                &[("cache_bytes", 4096)],
            ))
            .expect("accepted");
        assert_eq!(
            rig.stores
                .catalog()
                .namespace_explode_budget("team")
                .unwrap(),
            Some(NO_CACHE),
            "a SUSPENDED fact does not get its plan's cache cap: the door refuses \
             this tenant, so the budget is the floor and the 4096 in the fact is \
             not applied (see cache_reclaim tests below)"
        );
    }
    // A fresh slot over the same data root: what a reboot does.
    let reborn = rig.slot();
    let plane = rig.plane(&reborn);
    let facts = plane.entitlement_list().unwrap();
    assert_eq!(facts.len(), 1, "{facts:?}");
    assert_eq!(facts[0].state, PbState::Suspended as i32);
    assert_eq!(reborn.counts().suspended, 1);
    // Enforced after the reload, not merely listed.
    let dispatch = rig.dispatch(&reborn);
    let owner = Principal {
        id: "team".into(),
        name: "team".into(),
        kind: PrincipalKind::User,
        created: 0,
    };
    let err = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("suspended after reload");
    assert!(matches!(err, DispatchError::Plan { .. }), "{err:?}");

    // The document tampered with (the state flipped to Paid behind the
    // signature): refused at boot, logged, and the namespace is Free — never
    // Paid, because the signature no longer covers it.
    let store = gunnar_core::EntitlementStore::new(Arc::clone(rig.stores.control_store())).unwrap();
    let mut stored = store.get("team").unwrap().unwrap();
    stored.state = EntitlementState::Paid;
    store.set(stored).unwrap();
    let tampered = rig.slot();
    assert_eq!(
        tampered.verdict("team", gunnar_ssh::PlanAction::Write),
        gunnar_ssh::PlanVerdict::Allow,
        "an unverifiable fact is Free (allowed), not the Paid it claims"
    );
    assert_eq!(
        tampered.counts().paid,
        0,
        "the counts are what is ENFORCED, and nothing is"
    );
    assert!(
        tampered.enforced_state("team").is_none(),
        "the cache holds NO fact for it: the tampered fact did not load"
    );
}

#[test]
fn list_shows_the_latest_fact_per_namespace() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("a");
    rig.tenant("b");
    plane
        .entitlement_set(rig.signed(&rig.key, "a", State::Paid, &[]))
        .unwrap();
    plane
        .entitlement_set(rig.signed(&rig.key, "b", State::Grace, &[]))
        .unwrap();
    let (_, seq) = plane
        .entitlement_set(rig.signed(&rig.key, "a", State::Suspended, &[]))
        .unwrap();
    assert_eq!(seq, 2, "three accepted facts are three lines, 0..=2");
    let facts = plane.entitlement_list().unwrap();
    assert_eq!(facts.len(), 2, "one row per namespace: {facts:?}");
    assert_eq!(
        (facts[0].namespace.as_str(), facts[0].state),
        ("a", PbState::Suspended as i32)
    );
    assert_eq!(
        (facts[1].namespace.as_str(), facts[1].state),
        ("b", PbState::Grace as i32)
    );
    // Four lines, not three: the third fact is Suspended, and a suspension
    // journals what its derived cache gave back on the line after the fact
    // that caused it.
    let lines = rig.log_lines();
    assert_eq!(
        lines.len(),
        4,
        "the log keeps the history; List keeps the latest: {lines:?}"
    );
    assert_eq!(
        lines
            .iter()
            .filter(|l| l.contains("\"cache_reclaim\""))
            .count(),
        1,
        "one reclaim line, for the one namespace that fell to Suspended: {lines:?}"
    );
    let counts = slot.counts();
    assert_eq!((counts.paid, counts.grace, counts.suspended), (0, 1, 1));
}

#[test]
fn a_plane_without_a_monetize_key_refuses_every_set_by_name() {
    let rig = Rig::new();
    let plane = CoreControlPlane::new(Arc::clone(&rig.stores));
    let err = plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
        .expect_err("no key, no verification, no acceptance");
    assert!(err.to_string().contains("--monetize-pubkey"), "{err}");
}

// ───────────────────────────────────────────────────────────────────────────
// Step 3: the check, at the one choke point, each refuse with its allow twin
// ───────────────────────────────────────────────────────────────────────────

#[test]
fn a_suspended_push_is_refused_by_name_and_the_same_push_after_a_paid_fact_succeeds() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);

    // Unknown namespace = Free = allowed. The gate's silence for a tenant
    // monetize never mentioned is the product's default, not a refusal.
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("no fact at all: Free, push allowed");

    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
        .unwrap();
    let err = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("a Suspended tenant's push is refused");
    let DispatchError::Plan { namespace, line } = &err else {
        panic!("refused for the wrong reason: {err:?}");
    };
    assert_eq!(namespace, "team");
    // The line names the state, the date and the URL — all three.
    assert!(line.contains("expired 2026-10-01"), "the date: {line}");
    assert!(
        line.contains("writes closed"),
        "the state, as what it means: {line}"
    );
    assert!(
        line.ends_with("renew at https://gunnar.rs/billing/team"),
        "the URL, naming the tenant: {line}"
    );
    assert_eq!(
        err.client_message().as_deref(),
        Some(line.as_str()),
        "and the client is told exactly that"
    );
    // LFS upload is a write too.
    let err = dispatch
        .authorise_service(
            &owner,
            None,
            GitService::LfsTransfer(Operation::Upload),
            repo("team"),
        )
        .expect_err("LFS upload is a write");
    assert!(matches!(err, DispatchError::Plan { .. }), "{err:?}");
    // Retention: the same refusal, and it says the data is kept.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Retention, &[]))
        .unwrap();
    let err = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("Retention refuses writes");
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(line.contains("data kept for export"), "{line}");

    // The allow twin: a Paid fact, and the identical push goes through.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
        .unwrap();
    let request = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("Paid: the same push succeeds");
    assert_eq!(request.access, Level::Admin);
    assert_eq!(request.plan_notice, None, "Paid carries no warning");
    // Grace: allowed, with the warning line on the request.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Grace, &[]))
        .unwrap();
    let request = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("Grace: allowed");
    let notice = request.plan_notice.expect("Grace carries the warning line");
    assert!(
        notice.contains("expired 2026-10-01")
            && notice.ends_with("renew at https://gunnar.rs/billing/team"),
        "{notice}"
    );
}

#[test]
fn the_owner_always_clones_and_anonymous_is_closed_when_suspended() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);
    let anonymous = Principal::anonymous();

    // Before any fact: the public repo is readable by a stranger.
    dispatch
        .authorise_service(&anonymous, None, GitService::UploadPack, repo("team"))
        .expect("Free: anonymous ls-refs/clone of a Public repo");

    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
        .unwrap();
    // Never hold data hostage: the owner's clone succeeds in every state.
    let request = dispatch
        .authorise_service(&owner, None, GitService::UploadPack, repo("team"))
        .expect("the owner clones from a Suspended namespace");
    assert_eq!(request.plan_notice, None);
    dispatch
        .authorise_service(
            &owner,
            None,
            GitService::LfsTransfer(Operation::Download),
            repo("team"),
        )
        .expect("…and downloads their LFS objects");
    // Anonymous read of a Public repo in a Suspended namespace: refused.
    let err = dispatch
        .authorise_service(&anonymous, None, GitService::UploadPack, repo("team"))
        .expect_err("anonymous ls-refs on a Suspended public repo is refused");
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(line.contains("anonymous access closed"), "{line}");
    // The allow twin: Paid again, and the stranger is back.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
        .unwrap();
    dispatch
        .authorise_service(&anonymous, None, GitService::UploadPack, repo("team"))
        .expect("Paid: anonymous read allowed again");
    // A Machine principal (replication) is never asked: a standby must keep
    // receiving a lapsed tenant's data or it diverges from the primary.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
        .unwrap();
    let machine = Principal {
        id: "replicator".into(),
        name: "replicator".into(),
        kind: PrincipalKind::Machine,
        created: 0,
    };
    rig.stores.auth().add_principal(machine.clone()).unwrap();
    rig.stores
        .auth()
        .grant(gunnar_core::Grant {
            principal: "replicator".into(),
            scope: gunnar_core::Scope::Server,
            level: Level::Write,
        })
        .unwrap();
    dispatch
        .authorise_service(&machine, None, GitService::ReceivePack, repo("team"))
        .expect("replication into a Suspended namespace is not a tenant write");
}

#[test]
fn a_push_at_the_pack_quota_is_refused_before_the_bytes_and_under_it_is_not() {
    use gunnar_store::conformance::pack::PackBuilder;
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);
    // Put ~200 kB of pack in the namespace.
    let repo_row = rig.stores.catalog().get(&repo("team")).unwrap().unwrap();
    let handle = rig.stores.repo_store(&repo_row).unwrap();
    let mut pb = PackBuilder::new(gix_hash::Kind::Sha256);
    pb.object(gix_object::Kind::Blob, vec![b'q'; 200_000]);
    handle.serve().put_pack(&pb.build().unwrap().bytes).unwrap();
    drop(handle);
    rig.stores.close_repo(&repo("team"));
    let held = plane.usage(Some("team")).unwrap()[0].pack_bytes;
    assert!(held > 200_000, "the fixture is on disk: {held}");

    // A cap BELOW what is held: refused, naming the numbers and the URL.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", held - 1)]))
        .unwrap();
    let err = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("at the quota: refused before any byte");
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(
        line.contains("pack quota") && line.contains(&format!("{held} of {} bytes", held - 1)),
        "{line}"
    );
    assert!(line.ends_with("https://gunnar.rs/billing/team"), "{line}");
    // Reads are untouched by a quota.
    dispatch
        .authorise_service(&owner, None, GitService::UploadPack, repo("team"))
        .expect("a full tenant still clones");
    // The allow twins: room under the cap, and no cap at all (0 = unlimited).
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", held + 1)]))
        .unwrap();
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("under the cap: allowed");
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", 0)]))
        .unwrap();
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("0 is unlimited");
    // A Suspended tenant at the quota is told they are suspended, not full.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[("pack_bytes", 1)]))
        .unwrap();
    let err = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .unwrap_err();
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(
        line.contains("writes closed") && !line.contains("quota"),
        "{line}"
    );
}

/// ★ **At an estate that SELLS room, a person's account with no fact may push nothing**
/// until its fact lands (the free-room leak's last window, 2026-10-08); its clone is never
/// touched. The seller's own namespace, a fact that lands, and an estate that does not sell
/// (nothing fed: a sold private estate) keep "no fact is uncapped".
#[test]
fn at_a_selling_estate_a_person_with_no_fact_pushes_nothing_until_its_fact_lands() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("nothing fed: no fact is uncapped, as always");
    slot.sells_room_flag()
        .store(true, std::sync::atomic::Ordering::Relaxed);
    let err = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("a selling estate: no room yet");
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(
        line.starts_with(gunnar_grpc::selling::NO_ROOM_YET)
            && line.ends_with("https://gunnar.rs/billing/team"),
        "{line}"
    );
    dispatch
        .authorise_service(&owner, None, GitService::UploadPack, repo("team"))
        .expect("a clone is never refused");
    // The fact lands (the shop's account fact, or a bought room): the plan rules again.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", 10 << 30)]))
        .unwrap();
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("its fact rules");
    // The seller's own: today's rule.
    let op = rig.tenant("nordisk");
    rig.stores
        .auth()
        .grant(gunnar_core::Grant {
            principal: "nordisk".into(),
            scope: gunnar_core::Scope::Server,
            level: Level::Admin,
        })
        .unwrap();
    dispatch
        .authorise_service(&op, None, GitService::ReceivePack, repo("nordisk"))
        .expect("the seller's own namespace");
}

/// **The mid-upload ceiling the front door hands to the receive loop.**
///
/// `a_push_at_the_pack_quota_is_refused_before_the_bytes_and_under_it_is_not`
/// above covers the refusal for a tenant who is ALREADY full. This covers the
/// one that was missing: a tenant with room, whose single push crosses the cap
/// **in flight**. A pack header carries an object count and not a byte count,
/// so nothing before the transfer can know the size — the number asserted here
/// is what `gunnar-wire` counts the pack against, and
/// `gunnar-wire/tests/pack_ceiling.rs` is where the cutting itself is proved.
///
/// Red first — MEASURED 2026-09-05, before `EntitlementSlot::pack_ceiling`
/// existed: `authorise_service` answered a `ServiceRequest` with
/// `pack_ceiling: None` for a capped, paying tenant, so the receive loop had no
/// number to hold the push to and read it to its end.
///
/// The arithmetic is asserted from the constants rather than as a literal
/// total, so the slack can be re-argued without rewriting a magic number — and
/// the two "not this" assertions underneath are what stop it from being a
/// restatement of the code: a ceiling equal to the remaining room, or one that
/// ignored what is held, would both satisfy an assertion written as
/// `ceiling > 0`.
#[test]
fn a_capped_tenant_carries_a_byte_ceiling_into_the_transfer() {
    use gunnar_server::entitlement::{PACK_CEILING_SLACK_DIVISOR, PACK_CEILING_SLACK_FLOOR_BYTES};
    use gunnar_store::conformance::pack::PackBuilder;
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);

    // ~200 kB held, so `held` is a real number off the disk and not zero.
    let repo_row = rig.stores.catalog().get(&repo("team")).unwrap().unwrap();
    let handle = rig.stores.repo_store(&repo_row).unwrap();
    let mut pb = PackBuilder::new(gix_hash::Kind::Sha256);
    pb.object(gix_object::Kind::Blob, vec![b'q'; 200_000]);
    handle.serve().put_pack(&pb.build().unwrap().bytes).unwrap();
    drop(handle);
    rig.stores.close_repo(&repo("team"));
    let held = plane.usage(Some("team")).unwrap()[0].pack_bytes;
    assert!(held > 200_000, "the fixture is on disk: {held}");

    // ── a big cap: the slack is the proportional term ─────────────────────
    let cap = 10 * 1024 * 1024 * 1024u64; // 10 GiB, so cap/16 = 640 MiB > 64 MiB
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", cap)]))
        .unwrap();
    let request = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("under the cap: allowed");
    let ceiling = request
        .pack_ceiling
        .expect("a capped tenant's push must carry a ceiling into the transfer");
    let slack = cap / PACK_CEILING_SLACK_DIVISOR;
    assert!(
        slack > PACK_CEILING_SLACK_FLOOR_BYTES,
        "this half of the test is about the proportional term winning"
    );
    assert_eq!(
        ceiling.bytes,
        (cap - held) + slack,
        "the ceiling is the room left under the cap plus its slack"
    );
    // The two shapes this could have been and is not.
    assert_ne!(
        ceiling.bytes,
        cap - held,
        "a ceiling with no slack cuts the push that would have landed exactly at the cap"
    );
    assert_ne!(
        ceiling.bytes,
        cap + slack,
        "the ceiling ignored what the namespace already holds"
    );
    // The refusal is a sentence a tenant can act on, not an indexer's opinion.
    assert!(
        ceiling.refusal.contains("pack quota")
            && ceiling.refusal.contains(&cap.to_string())
            && ceiling.refusal.contains(&held.to_string()),
        "{}",
        ceiling.refusal
    );
    assert!(
        ceiling.refusal.ends_with("https://gunnar.rs/billing/team"),
        "a refusal that does not say where to pay: {}",
        ceiling.refusal
    );

    // ── a small cap: the absolute floor wins ──────────────────────────────
    //
    // 256 MiB / 16 is 16 MiB, smaller than one ordinary push, which is the
    // whole reason the floor exists. Without it a tenant with 200 kB held would
    // be cut mid-clone by arithmetic rather than by their plan.
    let small = 256 * 1024 * 1024u64;
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", small)]))
        .unwrap();
    let request = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("allowed");
    assert_eq!(
        request.pack_ceiling.expect("a ceiling").bytes,
        (small - held) + PACK_CEILING_SLACK_FLOOR_BYTES,
        "under a small cap the absolute floor is the slack, not cap/{PACK_CEILING_SLACK_DIVISOR}"
    );

    // ── the twins: no ceiling where there is nothing to hold ──────────────
    //
    // A gate that answered `Some` for everything would satisfy every assertion
    // above and would cut a clone (measured, not asserted).
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", 0)]))
        .unwrap();
    assert_eq!(
        dispatch
            .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
            .expect("0 is unlimited")
            .pack_ceiling,
        None,
        "an uncapped plan must not carry a ceiling"
    );
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", cap)]))
        .unwrap();
    assert_eq!(
        dispatch
            .authorise_service(&owner, None, GitService::UploadPack, repo("team"))
            .expect("a clone")
            .pack_ceiling,
        None,
        "a read carries no byte ceiling: nothing it does grows the tenant's data"
    );
}

#[test]
fn admin_stats_counts_the_tenants_by_enforced_state() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    for ns in ["a", "b", "c", "d"] {
        rig.tenant(ns);
    }
    plane
        .entitlement_set(rig.signed(&rig.key, "a", State::Paid, &[]))
        .unwrap();
    plane
        .entitlement_set(rig.signed(&rig.key, "b", State::Grace, &[]))
        .unwrap();
    plane
        .entitlement_set(rig.signed(&rig.key, "c", State::Suspended, &[]))
        .unwrap();
    plane
        .entitlement_set(rig.signed(&rig.key, "d", State::Retention, &[]))
        .unwrap();
    let extras = plane.stats_extras().unwrap();
    assert_eq!(
        (
            extras.tenants_paid,
            extras.tenants_grace,
            extras.tenants_suspended
        ),
        (1, 1, 2),
        "paid 1, grace 1, suspended 2 (Suspended + Retention)"
    );
    // The band reads the same slot and prints the same three numbers.
    let view = gunnar_server::dashboard::TenantView::new();
    let for_band = Arc::clone(&slot);
    view.fill(move || for_band.counts());
    assert_eq!(
        view.counts(),
        Some(gunnar_server::dashboard::TenantCounts {
            paid: 1,
            grace: 1,
            suspended: 2
        })
    );
    // And a plane with no slot counts nothing — zeros, not a guess.
    let bare = CoreControlPlane::new(Arc::clone(&rig.stores))
        .stats_extras()
        .unwrap();
    assert_eq!(
        (
            bare.tenants_paid,
            bare.tenants_grace,
            bare.tenants_suspended
        ),
        (0, 0, 0)
    );
}

/// **Both gates, in the server's order** (`metered` build): the disk-headroom
/// gate is the first link and the entitlement gate the second, wired by the
/// SAME `serve::front_control` the binary runs. A full disk outranks a
/// Suspended tenant's line; a roomy disk lets the plan speak.
#[test]
fn the_metered_front_door_carries_the_disk_gate_first_and_the_plan_gate_second() {
    use gunnar_ssh::{DiskFloor, DiskHeadroomGate};

    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
        .unwrap();
    let gate = |bytes: u64| {
        Arc::new(DiskHeadroomGate::new(
            rig.stores.root(),
            DiskFloor { percent: 0, bytes },
        ))
    };

    let control = gunnar_server::serve::front_control(
        &rig.stores,
        Default::default(),
        gate(u64::MAX),
        Some(&slot),
    );
    assert_eq!(
        control
            .plan_gates()
            .iter()
            .map(|g| g.name())
            .collect::<Vec<_>>(),
        ["disk-headroom", "entitlement"],
        "two links, disk first: {control:?}"
    );
    let err = Dispatch::new(control)
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("refused");
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(
        line.starts_with(gunnar_ssh::AT_FLOOR) && !line.contains("renew at"),
        "a full disk is told about the disk, not the plan: {line}"
    );

    let control =
        gunnar_server::serve::front_control(&rig.stores, Default::default(), gate(1), Some(&slot));
    let err = Dispatch::new(control)
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("still refused — by the plan");
    let DispatchError::Plan { line, .. } = &err else {
        panic!("{err:?}")
    };
    assert!(
        line.ends_with("renew at https://gunnar.rs/billing/team"),
        "with room, the plan's line: {line}"
    );

    // No monetize key at all: the metered binary still carries the disk gate.
    let control =
        gunnar_server::serve::front_control(&rig.stores, Default::default(), gate(u64::MAX), None);
    assert_eq!(
        control
            .plan_gates()
            .iter()
            .map(|g| g.name())
            .collect::<Vec<_>>(),
        ["disk-headroom"]
    );
}

/// **The metered appliance's key, given INLINE, verifies a real signed fact.**
///
/// The path arm every other test here uses is unreachable on an appliance: the
/// installer only stages files onto `/data` under `korp.reinstall=wipe` and the
/// ESP is read-only at runtime, so a keep-upgrade can only reach a booting
/// gunnar through the kernel command line. This is that route, measured all the
/// way through — the key is spelled as the 64 hex characters a `korp.args=`
/// would carry, and the fact it accepts is signed with the matching private key
/// over `monetize_embed::signing::fact_message`.
///
/// The assertion is not `is_ok()`. It is that a fact signed by the RIGHT key is
/// accepted and one signed by a FORGER is refused — a config carrying the wrong
/// 32 bytes fails the first arm, and one that verifies nothing at all fails the
/// second.
#[test]
fn a_key_given_inline_accepts_the_signer_and_refuses_a_forger() {
    let dir = tempfile::tempdir().expect("tempdir");
    let stores = Arc::new(ServerStores::open(dir.path()).expect("stores"));
    let key = SigningKey::from_bytes(&[7u8; 32]);
    let forger = SigningKey::from_bytes(&[9u8; 32]);

    // Exactly what a kernel command line carries: the key as hex text.
    let hex: String = key
        .verifying_key()
        .to_bytes()
        .iter()
        .map(|b| format!("{b:02x}"))
        .collect();
    assert_eq!(hex.len(), 64, "the cmdline spelling is 64 hex characters");
    let inline: MonetizePubkey = hex.parse().expect("the hex key parses");

    let config = MeteredConfig::load(&inline, Some(BILLING)).expect("an inline key needs no file");
    assert_eq!(
        config.monetize_pubkey,
        Some(key.verifying_key().to_bytes()),
        "the inline key must be the signer's 32 verifying-key bytes"
    );

    let rig = Rig {
        _dir: dir,
        stores,
        key,
        forger,
        config,
        minted: std::sync::atomic::AtomicU64::new(0),
    };
    let slot = rig.slot();

    // The real signer is honoured...
    let fact = rig.signed(&rig.key, "acme", State::Paid, &[("cache_bytes", 1 << 30)]);
    slot.set(fact)
        .expect("a fact signed by the inline key is accepted");
    assert_eq!(
        slot.enforced_state("acme"),
        Some(EntitlementState::Paid),
        "the plan must have moved — an accepted fact that changes nothing is not acceptance"
    );

    // ...and a forger is not. Without this arm the test would pass on a config
    // that verified nothing at all.
    let forged = rig.signed(&rig.forger, "acme", State::Suspended, &[]);
    slot.set(forged)
        .expect_err("a fact signed by another key must be refused");
    assert_eq!(
        slot.enforced_state("acme"),
        Some(EntitlementState::Paid),
        "the forged fact must not have moved the plan"
    );
}

// ───────────────────────────────────────────────────────────────────────────
// The allowance on `Usage.Read`: a fact's caps, on the tenant's own grant
// ───────────────────────────────────────────────────────────────────────────

/// `Usage.Read` as `principal`, through the real service over `plane`.
fn usage_read_as(
    plane: CoreControlPlane,
    principal: &str,
    namespace: &str,
) -> Result<gunnar_proto::ReadUsageResponse, tonic::Status> {
    use gunnar_proto::usage_server::Usage as _;
    let control: Arc<dyn gunnar_grpc::ControlPlane> = Arc::new(plane);
    let service = gunnar_grpc::UsageService::new(gunnar_grpc::ServiceContext::new(
        control,
        Arc::new(gunnar_grpc::EventBus::new(16)),
        gunnar_grpc::ServerConfig::default(),
    ));
    let mut request = tonic::Request::new(gunnar_proto::ReadUsageRequest {
        namespace: namespace.to_owned(),
    });
    request.extensions_mut().insert(gunnar_grpc::Caller {
        principal_id: principal.to_owned(),
        fingerprint: "SHA256:test".to_owned(),
        machine: false,
        authenticated: true,
    });
    tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()
        .expect("runtime")
        .block_on(service.read(request))
        .map(tonic::Response::into_inner)
}

/// **alice's cap is on her own `Usage.Read`; bob's is absent; and neither
/// needed `Entitlement.Get`'s server-wide grant.**
///
/// Two DIFFERENT caps on two different meters, so a cap copied into the
/// wrong field is visible; the five meters the fact does not name are absent,
/// not 0; and bob — a tenant with no fact — sees every cap absent on his own
/// read while being refused alice's. Seen red with `allowance_of` reading
/// `caps["pack_bytes"]` into `cache_bytes` (*"cache_bytes cap: left
/// Some(7340032) right Some(1572864)"*), and with the handler returning
/// `Allowance::default()` on the metered build (*"pack_bytes cap: left None
/// right Some(7340032)"*).
#[test]
fn a_tenants_cap_is_on_their_own_usage_read_and_a_tenant_without_a_fact_is_uncapped() {
    let rig = Rig::new();
    let slot = rig.slot();
    rig.tenant("alice");
    rig.tenant("bob");
    rig.plane(&slot)
        .entitlement_set(rig.signed(
            &rig.key,
            "alice",
            State::Paid,
            &[("pack_bytes", 7_340_032), ("cache_bytes", 1_572_864)],
        ))
        .expect("alice's fact");

    let hers = usage_read_as(rig.plane(&slot), "alice", "alice").expect("alice reads alice");
    let allowance = hers.allowance.expect("the allowance is always present");
    assert_eq!(allowance.pack_bytes, Some(7_340_032), "pack_bytes cap");
    assert_eq!(allowance.cache_bytes, Some(1_572_864), "cache_bytes cap");
    for (meter, cap) in [
        ("cold_bytes", allowance.cold_bytes),
        ("lfs_bytes", allowance.lfs_bytes),
        ("tombstoned_bytes", allowance.tombstoned_bytes),
        ("repos", allowance.repos),
        ("objects", allowance.objects),
    ] {
        assert!(
            cap.is_none(),
            "{meter}: the fact names no cap, so none is reported — not {cap:?}"
        );
    }
    // The meters came with it: this is `Usage.Read`, not `Entitlement.Get`.
    assert_eq!(hers.usage.expect("meters").namespace, "alice");

    let his = usage_read_as(rig.plane(&slot), "bob", "bob").expect("bob reads bob");
    // Every cap absent — and the seven enforcement words still there. A fact is
    // what puts a NUMBER on a meter; what this box DOES at a cap is a property
    // of the build and is reported to a tenant who has no fact exactly as it is
    // to one who has (`service::meters`). `Allowance::default()`, which this
    // read for, would assert the opposite: that a tenant on the free tier is
    // told nothing about which meters are doors.
    assert_eq!(
        his.allowance.expect("present"),
        gunnar_proto::Allowance {
            enforcement: gunnar_grpc::service::meters::enforcement(),
            ..gunnar_proto::Allowance::default()
        },
        "bob has no fact: every cap absent"
    );
    let refused =
        usage_read_as(rig.plane(&slot), "bob", "alice").expect_err("bob may not read alice");
    assert_eq!(refused.code(), tonic::Code::PermissionDenied, "{refused:?}");
}

/// ★ **What is left is gunnar's answer, on the tenant's own read**
/// (2026-10-04, the thin layer): cap − held for each capped meter, absent for
/// every uncapped one — and a tenant with no fact has nothing remaining
/// because nothing is capped. alice holds nothing yet, so what is left is
/// the whole cap.
#[test]
fn what_is_left_under_each_cap_is_on_the_tenants_own_usage_read() {
    let rig = Rig::new();
    let slot = rig.slot();
    rig.tenant("alice");
    rig.tenant("bob");
    rig.plane(&slot)
        .entitlement_set(rig.signed(
            &rig.key,
            "alice",
            State::Paid,
            &[("pack_bytes", 7_340_032), ("cache_bytes", 1_572_864)],
        ))
        .expect("alice's fact");

    let hers = usage_read_as(rig.plane(&slot), "alice", "alice").expect("alice reads alice");
    let held = hers.usage.clone().expect("meters");
    let left = hers.remaining.expect("remaining is always present");
    assert_eq!(left.pack_bytes, Some(7_340_032 - held.pack_bytes));
    assert_eq!(left.cache_bytes, Some(1_572_864 - held.cache_bytes));
    for (meter, value) in [
        ("cold_bytes", left.cold_bytes),
        ("lfs_bytes", left.lfs_bytes),
        ("tombstoned_bytes", left.tombstoned_bytes),
        ("repos", left.repos),
        ("objects", left.objects),
    ] {
        assert!(
            value.is_none(),
            "{meter} is uncapped, so nothing is 'remaining': {value:?}"
        );
    }
    let his = usage_read_as(rig.plane(&slot), "bob", "bob").expect("bob reads bob");
    assert_eq!(his.remaining, Some(gunnar_proto::Remaining::default()));
}

/// **A cap of 0 is ABSENT, because 0 is what the push door reads as
/// unlimited** (`a_push_at_the_pack_quota_…`: "0 is unlimited"). A reader of
/// the allowance must never be shown `Some(0)` for a tenant the door lets
/// push without limit. Seen red with the `> 0` filter removed: *"a 0 cap is
/// the door's 'unlimited' and must be ABSENT here, not Some(0)"*.
#[test]
fn a_cap_of_zero_is_reported_as_absent_because_the_door_reads_it_as_unlimited() {
    let rig = Rig::new();
    let slot = rig.slot();
    rig.tenant("team");
    rig.plane(&slot)
        .entitlement_set(rig.signed(
            &rig.key,
            "team",
            State::Paid,
            &[("pack_bytes", 0), ("cache_bytes", 4096)],
        ))
        .expect("the fact");
    let allowance = usage_read_as(rig.plane(&slot), "team", "team")
        .expect("read")
        .allowance
        .expect("present");
    assert_eq!(
        allowance.pack_bytes, None,
        "a 0 cap is the door's 'unlimited' and must be ABSENT here, not Some(0)"
    );
    // The twin: the non-zero cap beside it IS reported, so the rule is "0 is
    // absent" and not "everything is absent".
    assert_eq!(allowance.cache_bytes, Some(4096));
}

/// **A metered server started without `--monetize-pubkey` still answers
/// `Usage.Read`**, with every cap absent: it holds no facts (every namespace
/// is Free, `CoreControlPlane::entitlement` says so by name) and a tenant's
/// meters must not become unreadable because of it. Seen red with the
/// `FailedPrecondition` arm removed from `UsageService::allowance`: the read
/// fails with *"this metered server was started without `--monetize-pubkey`"*.
#[test]
fn a_metered_server_without_a_monetize_key_still_answers_usage_read_uncapped() {
    let rig = Rig::new();
    rig.tenant("team");
    let keyless = CoreControlPlane::new(Arc::clone(&rig.stores));
    let answer = usage_read_as(keyless, "team", "team")
        .expect("a keyless metered server reads meters; it simply holds no caps");
    // Uncapped, and labelled: a server with no key holds no facts, which is not
    // the same as a server that cannot say what its doors are.
    assert_eq!(
        answer.allowance.expect("present"),
        gunnar_proto::Allowance {
            enforcement: gunnar_grpc::service::meters::enforcement(),
            ..gunnar_proto::Allowance::default()
        }
    );
    assert_eq!(answer.usage.expect("meters").namespace, "team");
}

/// **The LFS wall, from the signed fact to the front door's answer.**
///
/// The twin of [`a_capped_tenant_carries_a_byte_ceiling_into_the_transfer`] one
/// wire over, and it exists because the pack ceiling did not cover LFS and
/// nothing else did either. `Dispatch::ask_plan` has always asked a write gate
/// for a ceiling on `LfsTransfer(Upload)` — and the LFS session never read it,
/// because a pack ceiling is measured in `pack_bytes` and an LFS object is not a
/// pack. So a tenant one byte under a 10 GiB `pack_bytes` cap could open an
/// upload session and put 8 GiB in it, under every limit the box had, and then
/// open another. `Usage.Read` billed every byte of it.
///
/// Red first — MEASURED 2026-09-07, before `EntitlementSlot::lfs_allowance`
/// existed: `gunnar_ssh::PlanGate` had no such method and `ServiceRequest` had
/// no such field, so this file did not compile:
///
/// ```text
/// error[E0599]: no method named `lfs_allowance` found for reference
///               `&Arc<EntitlementSlot>` in the current scope
/// ```
///
/// `gunnar-lfs/tests/namespace_allowance.rs` is where the refusal itself is
/// proved on the wire; this is the arithmetic and the wiring.
#[test]
fn a_capped_tenants_lfs_upload_carries_the_rooms_left_into_the_transfer() {
    use std::io::Write as _;
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);

    // ── real LFS bytes on disk, through the shipping store ────────────────
    //
    // Not a number injected into a fixture: `repo_bytes(..).lfs` walks
    // `<git_dir>/lfs/`, which is where `FsLfsStore` puts objects, and the
    // allowance has to be computed off the same walk `Usage.Read` bills from
    // (one implementation) or the number a tenant is refused at is not the number on their
    // bill.
    const PAYLOAD: &[u8] = b"an lfs object that is really on the disk\n";
    let repo_row = rig.stores.catalog().get(&repo("team")).unwrap().unwrap();
    let handle = rig.stores.repo_store(&repo_row).unwrap();
    let lfs = gunnar_lfs::FsLfsStore::open_or_init(handle.git_dir()).unwrap();
    let mut hasher = gix_hash::hasher(gix_hash::Kind::Sha256);
    hasher.update(PAYLOAD);
    let oid = match hasher.try_finalize().unwrap() {
        gix_hash::ObjectId::Sha256(d) => gunnar_lfs::Oid::from_digest(d),
        other => unreachable!("{other:?}"),
    };
    use gunnar_lfs::LfsStore as _;
    let mut pending = lfs.begin_write(&oid, PAYLOAD.len() as u64).unwrap();
    pending.write_all(PAYLOAD).unwrap();
    pending.commit().unwrap();
    drop(lfs);
    drop(handle);
    rig.stores.close_repo(&repo("team"));

    let held = plane.usage(Some("team")).unwrap()[0].lfs_bytes;
    assert!(
        held >= PAYLOAD.len() as u64,
        "the fixture must be on disk and in the meter: {held}"
    );

    // ── the wall ──────────────────────────────────────────────────────────
    let cap = 10 * 1024 * 1024 * 1024u64;
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("lfs_bytes", cap)]))
        .unwrap();
    let request = dispatch
        .authorise_service(
            &owner,
            None,
            GitService::LfsTransfer(Operation::Upload),
            repo("team"),
        )
        .expect("under the cap: allowed");
    // The gate hands back a `NamespaceAllowance` — the measured number bound to
    // the ledger standing that counts sibling uploads. What is asserted here is
    // the measurement, so read it through `allowance()`; the charging half has
    // its own tests in `gunnar-lfs`.
    let namespace_allowance = request
        .lfs_allowance
        .expect("a capped tenant's lfs upload must carry its room into the transfer");
    let allowance = namespace_allowance.allowance();
    assert_eq!(
        allowance.bytes,
        cap - held,
        "the room is the cap minus what is held, EXACTLY — an LFS object is \
         stored raw and its size is declared before the payload, so there is \
         none of the wire-versus-stored uncertainty the pack ceiling adds slack \
         for"
    );
    // The two shapes this could have been and is not. Either would satisfy an
    // assertion written as `allowance.bytes > 0`.
    assert_ne!(allowance.bytes, cap, "the allowance ignored what is held");
    assert!(
        !allowance.refusal.is_empty()
            && allowance.refusal.contains("lfs room left")
            && allowance.refusal.contains(&cap.to_string())
            && allowance.refusal.contains(&held.to_string()),
        "the sentence a tenant reads must name the cap and what is held: {}",
        allowance.refusal
    );
    assert!(
        allowance
            .refusal
            .ends_with("https://gunnar.rs/billing/team"),
        "a refusal that does not say where to pay: {}",
        allowance.refusal
    );

    // ── the twins: no allowance where there is nothing to hold ────────────
    //
    // A gate that answered `Some` for everything would satisfy every assertion
    // above and would refuse a `git lfs pull` (measured, not asserted).
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("lfs_bytes", 0)]))
        .unwrap();
    assert!(
        dispatch
            .authorise_service(
                &owner,
                None,
                GitService::LfsTransfer(Operation::Upload),
                repo("team")
            )
            .expect("0 is unlimited")
            .lfs_allowance
            .is_none(),
        "an uncapped plan must not carry an lfs allowance"
    );
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("lfs_bytes", cap)]))
        .unwrap();
    assert!(
        dispatch
            .authorise_service(
                &owner,
                None,
                GitService::LfsTransfer(Operation::Download),
                repo("team")
            )
            .expect("a download")
            .lfs_allowance
            .is_none(),
        "a download carries no allowance: nothing it does grows the tenant's data"
    );

    // ── and the meters stay apart ─────────────────────────────────────────
    //
    // The load-bearing negative. A `pack_bytes` cap must NOT silently bound the
    // LFS tier: `Usage.Read` reports `allowance.lfs_bytes` ABSENT for this fact,
    // absent has one documented meaning (uncapped), and a door that refused at a
    // number no surface shows is the support incident this work exists to
    // prevent. What this asserts is that gunnar's wall is honest, not that the
    // tier is safe — a plan that does not buy `lfs_bytes` still has an unbounded
    // one, and that is a fact about what monetize sells.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[("pack_bytes", cap)]))
        .unwrap();
    assert!(
        dispatch
            .authorise_service(
                &owner,
                None,
                GitService::LfsTransfer(Operation::Upload),
                repo("team")
            )
            .expect("allowed")
            .lfs_allowance
            .is_none(),
        "a pack_bytes cap must not become an lfs_bytes wall behind the tenant's back"
    );
}

/// **A metered appliance with no `--billing-url` REFUSES TO BOOT.**
///
/// This is the metered half of the open product's "no money here" rule. The
/// open half is `tests/open_build_speaks_no_money.rs`, which asserts the
/// default build's command line never says the word; this asserts that the
/// build which *may* say it is never allowed to say Vetra's URL on somebody
/// else's behalf.
///
/// What was here before was `unwrap_or("https://gunnar.rs/billing")` in
/// `gunnar_server::dispatch`. A silent default is the worst shape available
/// for this particular string: the box boots, the plans enforce correctly, and
/// the only symptom is the last clause of every refusal a tenant reads —
/// pointing at the page of whoever wrote the fallback rather than whoever runs
/// the appliance. Nothing fails; somebody else's customers just arrive at your
/// checkout.
///
/// The alternative was to tolerate the absence and let refusals carry no link.
/// Rejected: this URL is the ONLY way out of a refusal — it is in the Grace
/// warning, in the `PlanGate` verdict and in the boot log — so an appliance
/// without one refuses tenants into a dead end, and nobody finds out until the
/// support tickets. One line at boot, read by the one person who can fix it in
/// one flag, is the cheap failure.
#[test]
fn a_metered_build_without_a_lapse_url_refuses_at_boot() {
    let dir = tempfile::tempdir().expect("tempdir");
    let key = SigningKey::from_bytes(&[7u8; 32]);
    let pubkey = dir.path().join("monetize.pub");
    std::fs::write(&pubkey, key.verifying_key().to_bytes()).expect("write key");

    let refusal = MeteredConfig::load(&MonetizePubkey::Path(pubkey.clone()), None)
        .expect_err("a metered build with no lapse URL must not start")
        .to_string();

    assert!(
        refusal.contains("--billing-url"),
        "the refusal must name the flag the operator has to add: {refusal}"
    );
    assert!(
        refusal.contains("--monetize-pubkey"),
        "and the flag whose presence made it required: {refusal}"
    );
    assert!(
        !refusal.contains("gunnar.rs"),
        "and it must NOT quietly suggest the URL it just refused to invent: {refusal}"
    );

    // The same key WITH a URL is accepted, so the assertion above cannot be
    // passing because `load` refuses this key for some other reason.
    let ok = MeteredConfig::load(&MonetizePubkey::Path(pubkey), Some(BILLING))
        .expect("the same key with a URL loads");
    assert_eq!(ok.billing_url, BILLING);
}

/// ★ UW-6: **the SITE's pay page is fed, and every refusal ends in it.** The
/// medium is constant (one signed medium for every estate), so the URL it bakes
/// is a placeholder; the installer's door feeds `billing_url` per site
/// (`https://<site>/billing/{tenant}`, a page that site's console serves), and
/// the slot takes it LIVE: the next refusal and Grace line name the site's own
/// page. The same URL again changes nothing; a URL that is not `https://` is
/// refused by name and the page in force stays.
#[test]
fn the_sites_fed_pay_page_replaces_the_mediums_in_every_refusal() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
        .unwrap();
    let refused = |dispatch: &Dispatch| match dispatch.authorise_service(
        &owner,
        None,
        GitService::ReceivePack,
        repo("team"),
    ) {
        Err(DispatchError::Plan { line, .. }) => line,
        other => panic!("a Suspended push is refused by the plan: {other:?}"),
    };
    assert!(
        refused(&dispatch).ends_with("renew at https://gunnar.rs/billing/team"),
        "the medium's page before any feed"
    );

    assert_eq!(
        slot.set_billing_url("https://test2.gunnar.rs/billing/{tenant}"),
        Ok(true),
        "a new page is taken"
    );
    let line = refused(&dispatch);
    assert!(
        line.ends_with("renew at https://test2.gunnar.rs/billing/team"),
        "the site's own page, naming the tenant: {line}"
    );
    assert_eq!(
        slot.set_billing_url("https://test2.gunnar.rs/billing/{tenant}"),
        Ok(false),
        "the same page: nothing moves"
    );
    assert_eq!(
        slot.set_billing_url("https://test2.gunnar.rs/billing"),
        Ok(false),
        "`/{{tenant}}` appended, as the flag's: the same page"
    );

    let err = slot
        .set_billing_url("http://test2.gunnar.rs/billing/{tenant}")
        .expect_err("not https");
    assert!(
        err.contains(gunnar_server::feed::FEED_BILLING_URL) && err.contains("https"),
        "refused by name: {err}"
    );
    assert!(
        refused(&dispatch).ends_with("https://test2.gunnar.rs/billing/team"),
        "a refused page leaves the one in force"
    );

    // Grace carries the same page.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Grace, &[]))
        .unwrap();
    let request = dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("Grace: allowed");
    assert!(request
        .plan_notice
        .expect("Grace warns")
        .ends_with("renew at https://test2.gunnar.rs/billing/team"));
}

// ───────────────────────────────────────────────────────────────────────────
// The cache a tenant the door refuses is no longer allowed to hold
//
// A plan lapsing is NOT a deletion: not one pack, not one ref, not one byte
// of anybody's history moves in any test below, and none of this code can
// move one. What it reclaims is the *derived* explode cache — regenerable
// from the packs it does not touch, never mirrored to a twin
// (`twin::under_root` refuses a cache path outright) — because a tenant who
// has stopped paying is holding space nobody can sell.
// ───────────────────────────────────────────────────────────────────────────

/// The reclaim record for `ns`, parsed out of the attestation log.
fn reclaim_lines(rig: &Rig, ns: &str) -> Vec<serde_json::Value> {
    rig.log_lines()
        .iter()
        .filter_map(|line| serde_json::from_str::<serde_json::Value>(line).ok())
        .filter_map(|value| value.get("cache_reclaim").cloned())
        .filter(|record| record.get("namespace").and_then(|n| n.as_str()) == Some(ns))
        .collect()
}

/// **The trap, asserted rather than trusted: `0` is unlimited.**
///
/// `Namespace::explode_budget_bytes` is `Option<u64>` where `None` is the
/// server default and `Some(0)` is "unlimited — a deliberate answer, not an
/// absent one", and the engine agrees (`over_budget` is `budget != 0 && …`).
/// The obvious spelling of "this tenant gets no cache" is therefore the exact
/// inverse of the intent, and nothing but a test says so out loud: a
/// suspended namespace on `Some(0)` would grow without limit on a full disk
/// and every dashboard would report it as capped.
#[test]
fn a_suspended_namespaces_budget_is_the_floor_and_never_the_zero_that_means_unlimited() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("lapsed");

    // Paid first, with a real cap, so the assertion below cannot pass on a
    // namespace that never had a budget at all.
    plane
        .entitlement_set(rig.signed(&rig.key, "lapsed", State::Paid, &[("cache_bytes", 8 << 30)]))
        .expect("paid");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("lapsed")
            .unwrap(),
        Some(8 << 30),
        "a paying tenant is on their plan's number"
    );

    // …and then suspended, with the SAME cap still in the fact. The plan's
    // number is not what a refused tenant gets.
    plane
        .entitlement_set(rig.signed(
            &rig.key,
            "lapsed",
            State::Suspended,
            &[("cache_bytes", 8 << 30)],
        ))
        .expect("suspended");
    let budget = rig
        .stores
        .catalog()
        .namespace_explode_budget("lapsed")
        .unwrap();
    assert_ne!(
        budget,
        Some(0),
        "0 is UNLIMITED at every layer; a suspended tenant on 0 would hold an \
         unbounded cache, which is the opposite of a reclaim"
    );
    assert_eq!(
        budget,
        Some(NO_CACHE),
        "the floor the type can express, and no more"
    );
}

/// Retention is the other refused state and reclaims the same way. Without
/// this arm the whole feature could be keyed on `Suspended` alone and a box
/// that went straight to Retention would keep paying for the cache.
#[test]
fn retention_reclaims_exactly_as_suspended_does() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("gone");

    plane
        .entitlement_set(rig.signed(
            &rig.key,
            "gone",
            State::Retention,
            &[("cache_bytes", 1 << 30)],
        ))
        .expect("retention");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("gone")
            .unwrap(),
        Some(NO_CACHE)
    );
    let records = reclaim_lines(&rig, "gone");
    assert_eq!(records.len(), 1, "one reclaim line: {records:?}");
    assert_eq!(records[0]["state"], "Retention");
}

/// **Grace must not reclaim.** A tenant inside the 14-day window is expected
/// to pay and come back; dropping their exploded objects makes the first push
/// after they pay re-inflate every delta chain it touches, for nothing —
/// Grace is short, and the space comes back by itself if they do not return.
#[test]
fn grace_keeps_its_cache_and_journals_no_reclaim() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("late");

    plane
        .entitlement_set(rig.signed(&rig.key, "late", State::Grace, &[("cache_bytes", 2 << 30)]))
        .expect("grace");

    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("late")
            .unwrap(),
        Some(2 << 30),
        "a tenant in Grace keeps the plan's cache: they are expected back"
    );
    assert!(
        reclaim_lines(&rig, "late").is_empty(),
        "Grace reclaims nothing, so there is nothing to journal: {:?}",
        rig.log_lines()
    );

    // The refuse twin, in the same test: the SAME tenant one rung further
    // down does reclaim, so the assertion above cannot be passing because the
    // reclaim never runs for anybody.
    plane
        .entitlement_set(rig.signed(
            &rig.key,
            "late",
            State::Suspended,
            &[("cache_bytes", 2 << 30)],
        ))
        .expect("suspended");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("late")
            .unwrap(),
        Some(NO_CACHE)
    );
    assert_eq!(reclaim_lines(&rig, "late").len(), 1);
}

/// **The way back up, from the fact's own caps and never from a default
/// invented here** — and the case that has no caps at all, which is the one
/// that used to strand a returning customer on the floor budget for ever.
#[test]
fn paying_again_restores_the_budget_from_the_facts_own_caps() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("back");
    rig.tenant("plain");

    // A plan that names a cap: suspended, then paid, lands on the fact's
    // number — not on 8 GiB, not on the server default.
    plane
        .entitlement_set(rig.signed(
            &rig.key,
            "back",
            State::Suspended,
            &[("cache_bytes", 4 << 30)],
        ))
        .expect("suspended");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("back")
            .unwrap(),
        Some(NO_CACHE)
    );
    plane
        .entitlement_set(rig.signed(&rig.key, "back", State::Paid, &[("cache_bytes", 3 << 30)]))
        .expect("paid again");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("back")
            .unwrap(),
        Some(3 << 30),
        "restored from THIS fact's caps, not from the one before it and not from a constant"
    );

    // A plan that names none: the floor budget was ours, so it is ours to
    // undo, back to `None` = the server's default. Left as `Some(1)` — which
    // is what the old "only write the row when the fact has a cap" rule did —
    // a customer who had just paid would read at uncached speed with the
    // catalog saying they were on the default.
    plane
        .entitlement_set(rig.signed(&rig.key, "plain", State::Suspended, &[]))
        .expect("suspended");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("plain")
            .unwrap(),
        Some(NO_CACHE)
    );
    plane
        .entitlement_set(rig.signed(&rig.key, "plain", State::Paid, &[]))
        .expect("paid again");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("plain")
            .unwrap(),
        None,
        "a plan with no cache cap goes back to the server's default, not to our floor"
    );
}

/// An operator's hand-set quota is not something a plan change may clear. The
/// restore path undoes OUR floor budget and nothing else that happens to be
/// on the row.
#[test]
fn the_restore_does_not_clear_a_quota_the_operator_set_by_hand() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("hand");

    // `gunnar namespace set-explode-budget hand 512M`, as admin.rs does it.
    rig.stores
        .catalog()
        .set_namespace_explode_budget("hand", Some(512 << 20))
        .expect("operator quota");

    // A capless Paid fact arrives. Nothing of the operator's is touched.
    plane
        .entitlement_set(rig.signed(&rig.key, "hand", State::Paid, &[]))
        .expect("paid");
    assert_eq!(
        rig.stores
            .catalog()
            .namespace_explode_budget("hand")
            .unwrap(),
        Some(512 << 20),
        "a plan change with no cache cap is not entitled to clear an operator's quota"
    );
}

/// **The reclaim is journalled per namespace, including when it is zero.**
///
/// The owner's question is "what came back", and a line that only appears
/// when the answer flatters the feature is not an answer: in this rig no
/// store is open, so the honest number is 0 and it is on the record as 0.
///
/// The second half is the trap that would have taken the whole log down.
/// `AttestationLog::read_indexed` hard-errors on any line it cannot parse as
/// a `PushAttestation`, skipping only the shapes it knows. A new record kind
/// whose key is not in that list makes every `gunnar verify` and every
/// transparency proof fail from the first suspension onward.
#[test]
fn the_reclaim_is_journalled_by_namespace_and_the_push_log_still_parses() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("one");
    rig.tenant("two");

    plane
        .entitlement_set(rig.signed(&rig.key, "one", State::Suspended, &[]))
        .expect("suspended");
    plane
        .entitlement_set(rig.signed(&rig.key, "two", State::Suspended, &[]))
        .expect("suspended");

    for ns in ["one", "two"] {
        let records = reclaim_lines(&rig, ns);
        assert_eq!(
            records.len(),
            1,
            "one line per namespace, not one for the box: {records:?}"
        );
        let record = &records[0];
        assert_eq!(record["state"], "Suspended");
        assert_eq!(record["budget_bytes"], NO_CACHE);
        assert_eq!(
            record["repos"], 1,
            "the namespace's one repository was looked at: {record}"
        );
        assert_eq!(
            record["bytes_freed"], 0,
            "no store is open in this rig, so 0 is the honest number and it is written \
             rather than omitted: {record}"
        );
    }

    // And the log a verifier reads is still a log: the reclaim lines are
    // skipped like the entitlement lines beside them, never choked on.
    let log = AttestationLog::under(rig.stores.root());
    assert!(
        log.read()
            .expect("the push log still parses past the reclaim lines")
            .is_empty(),
        "there were no pushes; the four non-push lines must not become four errors"
    );
    assert_eq!(rig.log_lines().len(), 4, "two facts and two reclaims");
}

/// **The measured arm: a store that IS open gives real bytes back, and the
/// journal carries the number.**
///
/// Everything above this point would pass on an implementation that wrote a
/// budget and reclaimed nothing — every rig in this file has its stores
/// closed, where `Engine::drop_explode_cache` correctly answers 0. So this
/// one pushes a real pack, reads every blob back through `GitServe::read` to
/// make the lazily-exploded pool exist, and then suspends the tenant with the
/// handle still held. The assertion is on bytes, not on an intention.
///
/// Nothing here deletes anything of the customer's: the pack is still there
/// afterwards and the same objects still read, which the tail of the test
/// asserts, because the whole claim of this feature is that only DERIVED
/// bytes move.
#[test]
fn an_open_store_gives_its_derived_bytes_back_and_the_journal_carries_the_number() {
    use gunnar_store::conformance::pack::PackBuilder;

    let rig = Rig::under_the_disk_line();
    // **The read cache refuses every refill on a disk at or past its line**
    // (znippy `exploded_cache::DISK_LINE_PERCENT`, owner 2026-09-28: past 80 %
    // the lazy pool gives its oldest segments back and writes nothing new).
    // That is the product working; a store on such a disk caches nothing, so
    // the reclaim below would measure nothing. Said by name, before anything
    // is read — not as "the reads must have produced a cache" afterwards.
    let full = disk_used_percent(rig._dir.path());
    assert!(
        full.is_some_and(|used| used < DISK_LINE_PERCENT),
        "this rig's store sits on a filesystem {full:?} % full, at or past the read cache's \
         {DISK_LINE_PERCENT} % disk line: the cache rightly refuses every write-back there"
    );
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    rig.tenant("busy");

    // **The pack has to be one the cache actually WANTS.** `worth_caching` is
    // `inflated <= 1 MiB && depth > 2`: a whole 256 KiB blob is declined
    // before a byte is copied, on purpose ("the cheapest thing a cache can do
    // is not cache"), so a fixture of fat base objects would leave the pool
    // empty and this test would be measuring nothing while looking green.
    // Deep chains of small objects are what the pool is for, so that is what
    // is pushed: 40 chains of depth 6, 64 KiB an object — ~10 MiB of
    // admissible content, comfortably past the 4 MiB write-back buffer that
    // makes a segment reach the disk.
    let path = repo("busy");
    let repo_row = rig
        .stores
        .catalog()
        .get(&path)
        .expect("row")
        .expect("exists");
    let handle = rig.stores.repo_store(&repo_row).expect("open");
    let mut pb = PackBuilder::new(gix_hash::Kind::Sha256);
    for chain in 0..40u32 {
        let mut body = vec![b'a' + (chain % 26) as u8; 64 * 1024];
        body[..4].copy_from_slice(&chain.to_le_bytes());
        let mut at = pb.object(gix_object::Kind::Blob, body.clone());
        for link in 0..6u32 {
            body[4..8].copy_from_slice(&link.to_le_bytes());
            at = pb.delta(at, body.clone());
        }
    }
    let fixture = pb.build().expect("pack");
    let oids = fixture.ids();
    handle.serve().put_pack(&fixture.bytes).expect("put_pack");
    handle.serve().index_now().expect("index");

    // The read that creates the cache. Twice: the first read inflates out of
    // the pack and writes back, the second is the one the cache is FOR, and
    // doing both is what makes this a reader rather than a validation pass.
    for _ in 0..2 {
        for oid in &oids {
            let got = handle
                .serve()
                .read(oid.as_bytes())
                .expect("read")
                .expect("present");
            assert_eq!(got.1.len(), 64 * 1024);
        }
    }
    let cached = rig
        .stores
        .engine()
        .explode_use()
        .into_iter()
        .find(|(dir, _)| dir == handle.git_dir())
        .map(|(_, band)| band.used())
        .unwrap_or(0);
    assert!(
        cached > 0,
        "the reads must have produced a cache, or the reclaim below measures nothing"
    );

    // Suspend, with the handle still open — the case the reclaim is for.
    plane
        .entitlement_set(rig.signed(&rig.key, "busy", State::Suspended, &[]))
        .expect("suspended");

    let records = reclaim_lines(&rig, "busy");
    assert_eq!(records.len(), 1, "{records:?}");
    let freed = records[0]["bytes_freed"].as_u64().expect("a number");
    assert!(
        freed > 0,
        "an OPEN store's derived cache must come back as bytes, not as an intention: {}",
        records[0]
    );
    assert_eq!(records[0]["repos_reclaimed"], 1);
    // The WHOLE band, not a slice of it. This fixture pushes blobs only, so
    // the eager commit-and-tree pool — which a reclaim deliberately keeps,
    // because it is the graph and not a cache — is empty here and the band is
    // entirely the lazy pool. A fixture with commits in it would make these
    // two differ by exactly the graph, which is the intended behaviour and
    // would need a different assertion, not a looser one.
    assert_eq!(
        freed, cached,
        "every derived byte the store was holding came back: {}",
        records[0]
    );
    let after = rig
        .stores
        .engine()
        .explode_use()
        .into_iter()
        .find(|(dir, _)| dir == handle.git_dir())
        .map(|(_, band)| band.used())
        .unwrap_or(0);
    assert_eq!(
        after, 0,
        "and the store is no longer holding it — the reclaim was applied, not reported"
    );

    // And the customer's data is untouched: the same objects still read, out
    // of the packs the reclaim did not go near.
    for oid in &oids {
        let got = handle
            .serve()
            .read(oid.as_bytes())
            .expect("read")
            .expect("still present");
        assert_eq!(
            got.1.len(),
            64 * 1024,
            "a reclaim that lost an object is a data loss bug"
        );
    }
}

// ───────────────────────────────────────────────────────────────────────────
// The replay guard: a fact is good once, and never again
// ───────────────────────────────────────────────────────────────────────────

/// **A captured `Paid` fact must not restore a tenant who has since lapsed.**
///
/// Nothing here is forged. Every fact is monetize's own, signed by monetize's
/// own key, and step 3 pushes the EXACT BYTES of step 1 back — which is all an
/// attacker who can reach `Entitlement.Set` (server-admin) has to keep. The
/// signature verifies, because it is a real signature; the question this test
/// asks is whether verifying is enough, and the answer must be no.
///
/// `paid_until` cannot answer it: the lapsed fact in step 2 carries the SAME
/// `paid_until` as the paid one in step 1 — that is what a lapse IS, the date
/// stayed put and the ladder moved past it — so there is no field in the fact
/// a box could compare to tell the replay from the original. Only something
/// monotonic in the SIGNED form can, which is why this test's fix is not local
/// to gunnar.
#[test]
fn a_captured_paid_fact_is_refused_after_the_tenant_lapsed() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);

    // 1. The tenant pays, and the wire bytes are CAPTURED.
    let captured = rig.signed(&rig.key, "team", State::Paid, &[]);
    plane
        .entitlement_set(captured.clone())
        .expect("Paid is accepted");
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("Paid: the push goes through");

    // 2. The tenant lapses. Same `paid_until`; the ladder moved, not the date.
    plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
        .expect("Suspended is accepted");
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("Suspended: the push is refused");

    // 3. THE REPLAY. The captured bytes, verbatim, months later.
    let refused = plane
        .entitlement_set(captured)
        .expect_err("a fact this box has already moved past is not accepted a second time");
    let message = format!("{refused:?}");
    assert!(
        message.contains("team"),
        "the refusal names the namespace: {message}"
    );

    // 4. And the service stayed withdrawn.
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("the replay did not restore the write door");
    assert_eq!(
        slot.enforced_state("team"),
        Some(EntitlementState::Suspended),
        "the box still enforces the lapse"
    );
}

/// **The poller's retry path must stay green.** `retry_pushes` re-sends a fact
/// the product never acknowledged, verbatim — same bytes, same stamp — and that
/// is how a lost push is repaired at all. The guard must not read it as a
/// replay, because the two look identical from the outside except for one
/// thing: a retry is the SAME fact, and a replay is an older one.
///
/// Written alongside the replay test on purpose. Get this wrong and the guard
/// trades a rare attack for a common outage.
#[test]
fn the_same_fact_pushed_again_is_idempotent_and_is_not_a_replay() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let owner = rig.tenant("team");
    let dispatch = rig.dispatch(&slot);

    // One fact, minted once. Both pushes carry these exact bytes — which is what
    // `retry_pushes` does after an unacknowledged push.
    let fact = rig.signed_at(
        &rig.key,
        "team",
        State::Paid,
        &[("pack_bytes", 1 << 30)],
        Some(ISSUED_AT),
    );
    let (first, seq_one) = plane.entitlement_set(fact.clone()).expect("the push");
    let (again, seq_two) = plane
        .entitlement_set(fact.clone())
        .expect("the RETRY of the same push");
    assert_eq!(first, again, "the same fact enforces the same state");
    assert_ne!(
        seq_one, seq_two,
        "and the retry is its own attestation line, honestly"
    );
    assert_eq!(
        slot.enforced_state("team"),
        Some(EntitlementState::Paid),
        "nothing moved, because nothing was different"
    );
    dispatch
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect("the tenant is still served");

    // A third push, still the same bytes, after a reboot: the latch is in the
    // document and the retry survives it too.
    let reopened = rig.slot();
    rig.plane(&reopened)
        .entitlement_set(fact)
        .expect("a retry that arrives after a restart is still not a replay");

    // …but a DIFFERENT fact at the same instant is not a retry, and is refused.
    let twin = rig.signed_at(&rig.key, "team", State::Suspended, &[], Some(ISSUED_AT));
    let err = rig
        .plane(&reopened)
        .entitlement_set(twin)
        .expect_err("same instant, different fact: not newer, so not accepted");
    assert!(matches!(err, ControlError::PermissionDenied(_)), "{err:?}");
}

/// ★ **An unstamped fact is refused, on a new namespace too** (stinky row 12).
/// The grandfather clause accepted facts with no issue time until the
/// namespace's first stamped one, so a captured unstamped `Paid` fact could be
/// pushed for any namespace that had never been stamped — and over and over for
/// one that never would be. monetize stamps every fact it signs and the
/// monetize this talks to is a test system, so there is no legacy to keep: no
/// issue time, no fact.
#[test]
fn an_unstamped_fact_is_refused_even_for_a_namespace_that_has_none() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);

    // A namespace with no fact at all: the unstamped form is refused.
    let old = rig.signed_at(&rig.key, "team", State::Paid, &[], None);
    let err = plane
        .entitlement_set(old.clone())
        .expect_err("an unstamped fact for a fresh namespace");
    assert!(matches!(err, ControlError::PermissionDenied(_)), "{err:?}");
    assert_eq!(
        slot.enforced_state("team"),
        None,
        "and the refusal moved nothing"
    );

    // A stamped one is accepted…
    let stamped = rig.signed_at(&rig.key, "team", State::Suspended, &[], Some(ISSUED_AT));
    plane
        .entitlement_set(stamped)
        .expect("a stamped fact is accepted");

    // …and the unstamped form stays refused: the captured `Paid` from the top.
    let err = plane
        .entitlement_set(old)
        .expect_err("an unstamped fact for a namespace that has one");
    assert!(matches!(err, ControlError::PermissionDenied(_)), "{err:?}");
    assert_eq!(
        slot.enforced_state("team"),
        Some(EntitlementState::Suspended),
        "and the refusal moved nothing"
    );
}

/// **The latch is in the control document, so a reboot does not forget it.** A
/// guard held only in memory would be defeated by waiting for a restart, which
/// on an appliance is a thing that happens by itself.
///
/// The refusal is also read here for what it does NOT say: `Entitlement.Set` is
/// server-admin and `Get` is server-read today, but the words must not become
/// the way to read one tenant's billing state through a push at another.
#[test]
fn the_high_water_mark_survives_a_restart_and_the_refusal_says_nothing_extra() {
    let rig = Rig::new();
    let owner = rig.tenant("team");

    let captured = {
        let slot = rig.slot();
        let plane = rig.plane(&slot);
        let captured = rig.signed(&rig.key, "team", State::Paid, &[]);
        plane.entitlement_set(captured.clone()).unwrap();
        plane
            .entitlement_set(rig.signed(&rig.key, "team", State::Suspended, &[]))
            .unwrap();
        captured
    };

    // A new slot over the same stores: what the appliance comes back as.
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    assert_eq!(
        slot.enforced_state("team"),
        Some(EntitlementState::Suspended),
        "the lapse survived the restart"
    );
    let err = plane
        .entitlement_set(captured)
        .expect_err("and so did the high-water mark");
    let ControlError::PermissionDenied(words) = &err else {
        panic!("{err:?}")
    };
    assert!(
        words.contains("team"),
        "the refusal names the namespace: {words}"
    );
    assert!(
        words.contains("replay"),
        "and says what it refused it as: {words}"
    );
    for leak in [
        "Suspended",
        "Paid",
        &ISSUED_AT.to_string(),
        &OCT_1_2026.to_string(),
    ] {
        assert!(
            !words.contains(leak),
            "the refusal must not carry {leak}: a caller who cannot read this namespace's fact \
             must not learn it by pushing at it — {words}"
        );
    }
    rig.dispatch(&slot)
        .authorise_service(&owner, None, GitService::ReceivePack, repo("team"))
        .expect_err("the replay did not restore the write door");
}

/// **An issue time that was added or bumped by hand is refused at the
/// signature**, not at the comparison — otherwise the guard would be its own
/// weapon: an unsigned stamp of `u64::MAX` would pin the namespace past every
/// fact monetize will ever mint for it.
#[test]
fn refuse_twin_a_hand_written_issue_time_is_refused_as_forged_and_pins_nothing() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);

    plane
        .entitlement_set(rig.signed_at(&rig.key, "team", State::Paid, &[], Some(ISSUED_AT)))
        .expect("a genuine stamped fact");

    // The same genuine fact with the stamp moved to the end of time.
    let mut bumped = rig.signed_at(&rig.key, "team", State::Paid, &[], Some(ISSUED_AT + 1));
    bumped.issued_unix_ms = Some(u64::MAX);
    let err = plane
        .entitlement_set(bumped)
        .expect_err("a bumped stamp is not monetize's word");
    let ControlError::PermissionDenied(words) = &err else {
        panic!("{err:?}")
    };
    assert!(
        words.contains("does not verify"),
        "refused as forged, not as stale: {words}"
    );

    // And nothing was pinned: the next genuine fact still lands.
    plane
        .entitlement_set(rig.signed_at(
            &rig.key,
            "team",
            State::Suspended,
            &[],
            Some(ISSUED_AT + 2),
        ))
        .expect("the namespace was not wedged by the attempt");
    assert_eq!(
        slot.enforced_state("team"),
        Some(EntitlementState::Suspended)
    );
}

// ───────────────────────────────────────────────────────────────────────────
// A restore under the WRONG monetize key
// ───────────────────────────────────────────────────────────────────────────

/// **A box restored under a monetize key that did not sign its facts keeps
/// every fact on disk, enforces none of them, and must SAY so — and must not
/// report a plan it does not enforce.**
///
/// This is the shape a twin restore takes when the promoted box is given the
/// wrong `--monetize-pubkey`: the control document came across byte for byte,
/// so every fact is still there; not one verifies, so every paying namespace is
/// served as Free. MEASURED 2026-09-21 before the fix, on this very rig:
/// `refused_at_boot` did not exist (the boot line said `tenants = 0`, the line a
/// healthy empty box logs), and `Entitlement.Get` answered `PAID` — out of the
/// store — for a namespace the cache and therefore the front door held Free.
///
/// Then the way back, because it is the operator's whole remedy: the RIGHT key,
/// and nothing else. No fact is re-pushed; re-opening the same document under
/// the key that signed it restores every plan. A re-push under the wrong key is
/// refused as forged, which is why the boot line says "never a re-push".
#[test]
fn a_box_restored_under_the_wrong_key_reports_no_plan_it_does_not_enforce() {
    let rig = Rig::new();
    rig.tenant("team");
    rig.tenant("acme");
    {
        let slot = rig.slot();
        let plane = rig.plane(&slot);
        plane
            .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
            .expect("genuine");
        plane
            .entitlement_set(rig.signed(&rig.key, "acme", State::Grace, &[]))
            .expect("genuine");
        // THE CONTROL: under the key that signed them, both are enforced and
        // both are reported, and nothing was refused.
        assert_eq!(slot.refused_at_boot(), 0);
        assert_eq!(plane.entitlement_refused_at_boot().unwrap(), None);
        assert!(plane.health_alarms().is_empty());
        assert_eq!(plane.entitlement_list().unwrap().len(), 2);
    }

    // The restore: the same stores, a different monetize key.
    let wrong = rig._dir.path().join("wrong.pub");
    std::fs::write(&wrong, rig.forger.verifying_key().to_bytes()).expect("write key");
    let wrong = MeteredConfig::load(&MonetizePubkey::Path(wrong), Some(BILLING)).expect("config");
    let slot =
        EntitlementSlot::open(Arc::clone(&rig.stores), &wrong).expect("a wrong key still boots");
    let plane = rig.plane(&slot);

    assert_eq!(
        slot.refused_at_boot(),
        2,
        "both stored facts were refused, and the box COUNTS them"
    );
    // ★ ON THE WIRE, not only in a log line: on the UpCloud machine there is no
    // serial console and the boot WARN reaches nobody (MEASURED 2026-09-21).
    // `Entitlement.List` carries the refusal and `Admin.Health` an alarm.
    let refused = plane
        .entitlement_refused_at_boot()
        .unwrap()
        .expect("Entitlement.List must carry the refusal");
    assert_eq!(refused.count, 2);
    assert_eq!(
        refused.namespaces,
        vec!["acme".to_string(), "team".to_string()]
    );
    assert!(
        refused.at_unix_ms > 0 && refused.reason.contains("monetize public key"),
        "{refused:?}"
    );
    let alarms = plane.health_alarms();
    assert_eq!(alarms.len(), 1, "{alarms:?}");
    assert_eq!(
        alarms[0].event, "entitlement.key_mismatch",
        "--monetize-vital is the default"
    );
    assert!(
        alarms[0].detail.contains("acme, team"),
        "the alarm names the namespaces: {}",
        alarms[0].detail
    );
    assert_eq!(alarms[0].count, 2);
    assert_eq!(slot.enforced_state("team"), None, "Free at the front door");
    assert_eq!(slot.counts().paid, 0);
    // ★ The reads agree with the door. Before the fix both of these answered
    // the stored fact: `PAID` with a renewal date nothing enforced.
    assert_eq!(
        plane.entitlement_get("team").unwrap(),
        None,
        "Entitlement.Get reported a plan the box does not enforce"
    );
    assert!(
        plane.entitlement_list().unwrap().is_empty(),
        "Entitlement.List listed facts the box refused"
    );

    // A re-push signed by the key that is NOT configured is refused, by name.
    let err = plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
        .expect_err("a fact the configured key did not sign must be refused");
    assert!(matches!(err, ControlError::PermissionDenied(_)), "{err:?}");

    // The remedy is the right key and nothing else: the facts never left.
    drop(plane);
    drop(slot);
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    assert_eq!(slot.refused_at_boot(), 0);
    assert_eq!(slot.enforced_state("team"), Some(EntitlementState::Paid));
    assert_eq!(
        plane.entitlement_refused_at_boot().unwrap(),
        None,
        "the right key refuses nothing"
    );
    assert!(plane.health_alarms().is_empty());
    assert_eq!(slot.enforced_state("acme"), Some(EntitlementState::Grace));
    assert_eq!(
        plane.entitlement_get("team").unwrap().map(|f| f.state),
        Some(PbState::Paid as i32)
    );
}

// ── `monetize_vital` (owner ruling 2026-09-22) ─────────────────────────────

/// The restore under another key, set up once: two facts on disk signed by `rig.key`, and a
/// slot opened under `rig.forger`'s key with `vital`.
fn restored_under_another_key(rig: &Rig, vital: bool) -> Arc<EntitlementSlot> {
    rig.tenant("team");
    rig.tenant("acme");
    {
        let slot = rig.slot();
        let plane = rig.plane(&slot);
        plane
            .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
            .expect("genuine");
        plane
            .entitlement_set(rig.signed(&rig.key, "acme", State::Grace, &[]))
            .expect("genuine");
        assert!(
            plane.maintenance_reasons().is_empty(),
            "the control: the right key is not maintenance"
        );
    }
    let other = rig._dir.path().join("other.pub");
    std::fs::write(&other, rig.forger.verifying_key().to_bytes()).expect("write key");
    let mut config =
        MeteredConfig::load(&MonetizePubkey::Path(other), Some(BILLING)).expect("config");
    config.vital = vital;
    EntitlementSlot::open(Arc::clone(&rig.stores), &config)
        .expect("a mismatched key still boots and serves")
}

/// A key mismatch at boot raises `entitlement.key_mismatch`, naming the namespaces, and the box
/// reports maintenance — and it still started.
#[test]
fn a_key_mismatch_raises_the_alarm_and_maintenance() {
    let rig = Rig::new();
    let slot = restored_under_another_key(&rig, true);
    let plane = rig.plane(&slot);
    assert!(slot.maintenance());
    assert_eq!(
        plane.maintenance_reasons(),
        vec!["entitlement.key_mismatch".to_string()]
    );
    let alarms = plane.health_alarms();
    assert_eq!(alarms.len(), 1, "{alarms:?}");
    assert_eq!(alarms[0].event, "entitlement.key_mismatch");
    assert_eq!(alarms[0].count, 2);
    assert!(
        alarms[0].detail.contains("acme, team") && alarms[0].detail.contains("MAINTENANCE"),
        "{}",
        alarms[0].detail
    );
}

/// The first fact that VERIFIES under the box's key clears both: monetize and the box agree again.
#[test]
fn a_new_verifying_fact_clears_the_alarm_and_maintenance() {
    let rig = Rig::new();
    let slot = restored_under_another_key(&rig, true);
    let plane = rig.plane(&slot);
    // A fact the box's key did NOT sign clears nothing.
    assert!(plane
        .entitlement_set(rig.signed(&rig.key, "team", State::Paid, &[]))
        .is_err());
    assert!(slot.maintenance(), "a refused fact is not a verifying one");
    // monetize, now holding the key this box trusts, pushes a fact: it verifies.
    plane
        .entitlement_set(rig.signed(&rig.forger, "team", State::Paid, &[]))
        .expect("verifies under the box's key");
    assert!(!slot.maintenance());
    assert!(plane.maintenance_reasons().is_empty());
    assert!(
        plane.health_alarms().is_empty(),
        "{:?}",
        plane.health_alarms()
    );
    assert_eq!(
        slot.enforced_state("team"),
        Some(gunnar_core::EntitlementState::Paid)
    );
}

/// `--monetize-vital false`: the same refusal is only logged — no alarm, no maintenance.
#[test]
fn with_monetize_vital_false_a_mismatch_only_logs() {
    let rig = Rig::new();
    let slot = restored_under_another_key(&rig, false);
    let plane = rig.plane(&slot);
    assert_eq!(
        slot.refused_at_boot(),
        2,
        "still counted and still on Entitlement.List"
    );
    assert!(plane.entitlement_refused_at_boot().unwrap().is_some());
    assert!(!slot.maintenance());
    assert!(plane.maintenance_reasons().is_empty());
    assert!(
        plane.health_alarms().is_empty(),
        "{:?}",
        plane.health_alarms()
    );
}

/// The server flag: `true` unless it is set to false, by flag or by `GUNNAR_MONETIZE_VITAL`.
#[test]
fn monetize_vital_defaults_to_true_and_parses_false() {
    use clap::Parser;
    let parse = |extra: &[&str]| {
        let mut argv = vec![
            "gunnar",
            "serve",
            "--monetize-pubkey",
            "1c3663248d60900e2996389fba4efa1d7179d6dbd08627d0426f16f94e44c4e6",
            "--billing-url",
            BILLING,
        ];
        argv.extend_from_slice(extra);
        match gunnar_common::cli::Cli::try_parse_from(argv)
            .expect("parses")
            .command
        {
            gunnar_common::cli::Command::Serve(a) => a.monetize_vital,
            _ => unreachable!(),
        }
    };
    assert!(parse(&[]));
    assert!(!parse(&["--monetize-vital", "false"]));
    assert!(parse(&["--monetize-vital", "true"]));
}

/// **The fed monetize key applies LIVE** (owner 2026-09-25: avoid restarts).
/// A metered box on a `fed` medium opens its slot KEYLESS; a fact signed by
/// monetize is refused with nothing moved (no key to check it with), and every
/// namespace is Free. The key arrives — through the SAME door the pairing loop
/// and the installer's feed use (`feed::monetize_arrived` → the registered
/// takers) — and the very same fact is then ACCEPTED and ENFORCED by the same
/// slot object, with no restart. A second, different key is refused by name.
#[test]
fn a_fed_monetize_key_applies_in_place_and_a_fact_signed_with_it_is_accepted_without_a_restart() {
    let rig = Rig::new();
    let keyless =
        MeteredConfig::awaiting_feed(Some(BILLING)).expect("a fed medium with a pay page");
    assert_eq!(keyless.monetize_pubkey, None);
    let slot =
        EntitlementSlot::open(Arc::clone(&rig.stores), &keyless).expect("a keyless slot opens");
    rig.tenant("acme");
    let paid = rig.signed(&rig.key, "acme", State::Suspended, &[]);
    let refused = slot
        .set(paid.clone())
        .expect_err("no key yet: nothing can be verified");
    assert!(
        refused.to_string().contains("no monetize key yet"),
        "{refused}"
    );
    assert_eq!(
        slot.verdict("acme", gunnar_ssh::PlanAction::Write),
        gunnar_ssh::PlanVerdict::Allow,
        "keyless: Free, as a box with no slot was"
    );

    // The key arrives while running, through the feed's door.
    gunnar_server::feed::record_monetize_in_force(None);
    let taker = Arc::clone(&slot);
    gunnar_server::feed::on_monetize_key(
        "entitlement slot (test)",
        Box::new(move |k| taker.set_key(k).map(|_| ())),
    );
    let hex: String = rig
        .key
        .verifying_key()
        .to_bytes()
        .iter()
        .map(|b| format!("{b:02x}"))
        .collect();
    let arrived = gunnar_server::feed::monetize_arrived(Some(&hex));
    assert!(
        matches!(
            arrived,
            Some(gunnar_server::feed::MonetizeArrival::Applied(_))
        ),
        "{arrived:?}"
    );
    assert_eq!(
        gunnar_server::feed::monetize_in_force(),
        Some(rig.key.verifying_key().to_bytes())
    );
    assert_eq!(
        gunnar_server::feed::monetize_arrived(Some(&hex)),
        None,
        "the same key again: nothing to do"
    );

    // The SAME slot, no restart: the fact is accepted and enforced.
    let (state, _) = slot
        .set(paid)
        .expect("a fact signed with the fed key is accepted without a restart");
    assert_eq!(state, EntitlementState::Suspended);
    assert!(
        matches!(
            slot.verdict("acme", gunnar_ssh::PlanAction::Write),
            gunnar_ssh::PlanVerdict::Refuse(_)
        ),
        "and enforced"
    );
    // A forged fact is still refused under the fed key.
    assert!(slot
        .set(rig.signed(&rig.forger, "acme", State::Paid, &[]))
        .is_err());
    // Another key while one is in force is refused by name, and nothing moves.
    let other = slot
        .set_key(&rig.forger.verifying_key().to_bytes())
        .expect_err("a second key is not taken silently");
    assert!(other.contains("[pairing.feed_mismatch]"), "{other}");
    assert_eq!(
        slot.set_key(&rig.key.verifying_key().to_bytes()),
        Ok(false),
        "the key in force: nothing to do"
    );
}

/// A keyless slot applies a key that the STORE already holds facts for: the
/// facts on disk are re-verified under it at once, as a boot under that key
/// would have — so a box restored before its key arrived is enforcing the
/// moment it does.
#[test]
fn a_key_applied_in_place_reverifies_the_facts_already_on_disk() {
    let rig = Rig::new();
    rig.tenant("acme");
    // A keyed slot stores a Suspended fact; the box "restarts" keyless.
    rig.slot()
        .set(rig.signed(&rig.key, "acme", State::Suspended, &[]))
        .expect("stored");
    let slot = EntitlementSlot::open(
        Arc::clone(&rig.stores),
        &MeteredConfig::awaiting_feed(Some(BILLING)).unwrap(),
    )
    .unwrap();
    assert_eq!(
        slot.verdict("acme", gunnar_ssh::PlanAction::Write),
        gunnar_ssh::PlanVerdict::Allow,
        "keyless: Free"
    );
    assert_eq!(slot.set_key(&rig.key.verifying_key().to_bytes()), Ok(true));
    assert!(
        matches!(
            slot.verdict("acme", gunnar_ssh::PlanAction::Write),
            gunnar_ssh::PlanVerdict::Refuse(_)
        ),
        "the stored fact is enforced the moment the key arrives"
    );
    assert_eq!(slot.refused_at_boot(), 0);
}

/// A fact with its paid time and its payment chosen (c-stale-suspend).
fn fact_paid(
    key: &SigningKey,
    ns: &str,
    state: State,
    paid_until: u64,
    source: &str,
    issued: u64,
) -> EntitlementFact {
    let mut fact = monetize_embed::EntitlementFact {
        tenant: TenantId(ns.to_owned()),
        plan: "10gb".into(),
        state,
        paid_until_unix_ms: Some(paid_until),
        caps: BTreeMap::new(),
        source: source.into(),
        signature: vec![],
        issued_unix_ms: Some(issued),
        issued_signature: vec![],
    };
    fact.signature = key
        .sign(&monetize_embed::signing::fact_message(&fact))
        .to_bytes()
        .to_vec();
    fact.issued_signature = key
        .sign(&monetize_embed::signing::fact_message_issued(&fact))
        .to_bytes()
        .to_vec();
    EntitlementFact {
        namespace: fact.tenant.0,
        plan: fact.plan,
        state: match state {
            State::Free => PbState::Free,
            State::Paid => PbState::Paid,
            State::Grace => PbState::Grace,
            State::Suspended => PbState::Suspended,
            State::Retention => PbState::Retention,
        } as i32,
        paid_until_unix_ms: fact.paid_until_unix_ms,
        caps: fact.caps,
        source: fact.source,
        signature: fact.signature,
        issued_unix_ms: fact.issued_unix_ms,
        issued_signature: fact.issued_signature,
    }
}

/// **c-stale-suspend.** monetize restored from an OLDER backup (its front laid
/// again) lost a renewal the box holds: its poller re-signs the older ledger's
/// verdict at the current time — Suspended, paid only until the old date, from
/// an older payment — and the replay guard, which compares only issue times,
/// took it: a customer who PAID was suspended. The box refuses a newer-stamped
/// fact that takes back paid time it holds, from a payment other than the one it
/// holds (the refusal reads as "already holds", so monetize's re-push files it
/// as held, not as a refused cap). A downgrade about the SAME payment (a
/// refund) and a lapse (the held paid time is over) still go through.
#[test]
fn a_restored_older_ledger_cannot_suspend_a_tenant_whose_renewal_the_box_holds() {
    let rig = Rig::new();
    let slot = rig.slot();
    let plane = rig.plane(&slot);
    let now = std::time::SystemTime::now()
        .duration_since(std::time::UNIX_EPOCH)
        .unwrap()
        .as_millis() as u64;
    let day = 24 * 3600 * 1000;
    plane
        .entitlement_set(fact_paid(
            &rig.key,
            "team",
            State::Paid,
            now + 60 * day,
            "payment:stripe:renewal-2",
            ISSUED_AT + 10,
        ))
        .expect("the renewal is taken");

    let stale = fact_paid(
        &rig.key,
        "team",
        State::Suspended,
        now - day,
        "payment:stripe:first",
        ISSUED_AT + 20,
    );
    let refused = plane
        .entitlement_set(stale)
        .expect_err("a restored ledger that lost the renewal must not suspend a tenant who paid");
    let words = format!("{refused}");
    assert!(
        words.contains("already holds") && words.contains("team"),
        "{words}"
    );
    assert_eq!(
        slot.enforced_state("team"),
        Some(gunnar_core::EntitlementState::Paid),
        "still paid"
    );

    // A refund of the payment the box holds is a real downgrade.
    plane
        .entitlement_set(fact_paid(
            &rig.key,
            "team",
            State::Suspended,
            now - day,
            "payment:stripe:renewal-2",
            ISSUED_AT + 30,
        ))
        .expect("a downgrade about the held payment goes through");
    assert_eq!(
        slot.enforced_state("team"),
        Some(gunnar_core::EntitlementState::Suspended)
    );

    // A lapse: the held paid time is over, any later verdict goes through.
    let other = rig.slot();
    let p2 = rig.plane(&other);
    p2.entitlement_set(fact_paid(
        &rig.key,
        "lapsed",
        State::Paid,
        now - 2 * day,
        "payment:stripe:a",
        ISSUED_AT + 40,
    ))
    .unwrap();
    p2.entitlement_set(fact_paid(
        &rig.key,
        "lapsed",
        State::Suspended,
        now - 2 * day,
        "payment:stripe:older",
        ISSUED_AT + 50,
    ))
    .expect("the held paid time is over: a lapse is no regression");
}