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

nordisk/monetize

crates/monetize-server/src/estate_order.rs

//! **A private gunnar, ordered: the `lay estate <company>` job.**
//!
//! `private-gunnar-ops/PRIVATE-GUNNAR.md`: a company buys `<company>.gunnar.rs`
//! on gunnar.rs's front page, and the order is one more job type in this
//! server's own queue — the queue that already runs the paid disk growth
//! ([`crate::grow`]). The ONE monetize (`monetize.ignalina.dk`) holds the money,
//! lays the new estate at its cloud, has the kit install gunnar on it, and
//! captures only when the new estate calls home (its first Fleet report;
//! monetize never dials an estate's own channels) and its PUBLIC front answers
//! the buyer's way in, as a customer reaches it (the sale check, S4).
//!
//! ```text
//!   ordered ──▶ held ──▶ laying ──▶ installing ──▶ paired ──▶ captured
//!      │          │         │            │            │
//!      │          └─────────┴────────────┴────────────┴──▶ failed ──▶ released
//!      └── the page expired unpaid ───────────────────────────────────▶ released
//! ```
//!
//! | phase | the step | the world it reads |
//! |---|---|---|
//! | `ordered` | `pay.reserve` was asked; the buyer is on the vendor's page | `pay.status`: `Reserved` → `held` (the estate's secrets are minted, [`crate::custody`]) |
//! | `held` | waits for a slot (`max_open`) | the other runs' phases |
//! | `laying` | `cloud.lay_estate` + the DNS records | the provider, by label (a retry adopts) |
//! | `installing` | the kit, invoked ([`Installer`]) on the laid servers | its exit and its verdict file |
//! | `paired` | the estate called home, its main serves its data, and the sale check proves its PUBLIC front (S4); then `pay.capture` | its boxes' Fleet reports ([`crate::fleet::heard_since`], [`crate::fleet::serves_since`]); `https://<host>`: the login page, the first-login door, exactly one `<account>/welcome` ([`Installer::sale_check`]); `pay.capture` |
//! | `failed` | `release_for` + DNS removed + `orphans_for` empty, then `pay.release` | the provider's read-back |
//!
//! # Journaled and resumable, like the growth
//!
//! The run (`estate-orders/<company>/run.json`) is written, atomically, after
//! every transition and before the next step starts; the cloud's own journal
//! (`estate-orders/<company>/journal`) has every create as an intent before
//! the call and a confirmation after. Nothing is held in memory that a restart
//! needs: [`EstateOrders::from_config`] reads every run back, and [`tick`] —
//! at start and every few seconds — drives every open run from the phase its
//! file names. Each step is safe to repeat: the provider adopts what an
//! earlier attempt laid (same reference, same title), the kit adopts what is
//! laid (`--laid`), the vendor's capture and release are idempotent on the
//! handle.
//!
//! # The money is never ahead of the estate
//!
//! Nothing is laid before the vendor says the money is HELD. Nothing is
//! captured before the estate calls home and its public front proves it serves
//! what was sold (the sale check, S4). A failure gives back everything bought
//! under the reference and proves it (`orphans_for` empty) BEFORE the hold is
//! released — a release with iron still billing would be monetize paying for
//! an estate nobody bought.
//!
//! # One writer per run
//!
//! Every write of a run reads it, takes a step and writes the WHOLE run back:
//! the driver (its provider and payment calls in between), and the page's
//! `Start`, `Renew` and `ChangePlan`. Each holds the run's pen (`Pens`) from
//! its read to its write, so none writes over another's. Reads never take it.

use std::collections::{BTreeMap, BTreeSet};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Condvar, Mutex};
use std::thread::ThreadId;
use std::time::{Duration, Instant};

use monetize_cloud::lay::{
    company_name_refusal, reference_of, DiskPlan, EstatePlan, LaidEstate, MachinePlan,
};
use monetize_cloud::Zone;
use monetize_pay::{ChargeHandle, ChargeRequest, ChargeStatus, Money};

use crate::custody::Custody;
use crate::state::AppState;

/// **The account that buys and owns an estate is PROVEN** (one shop,
/// 2026-10-07): the `estate` ticket THIS shop's own Gunnar mints for a
/// signed-in gunnar.rs account, checked by the shop's gunnar product.
pub mod account;
/// **Plan changes** on a delivered estate: main and front by the buyer, the
/// twin following main.
pub mod change;
/// **The customer's own domain**: the two records, the check, the wait.
pub mod domain;
/// The size ladder, Mini to Gigantic: the sign-up page's one − / +.
pub mod ladder;
/// **What it costs**: the provider's plans and price, the margin, the rate,
/// the six-month term, the buy-time check.
pub mod price;
pub mod site;
/// **After the capture**: the six-month term, its renewal, and the rule for a
/// customer who stops paying.
pub mod term;
pub mod terminate;
/// **The twin sizes itself**: the damped lag/load rule.
pub mod twin;
// The operator sends a laid site's first sign-in link again (owner 2026-10-22).
pub mod first_link;
// MAIL-RELAY + NIGHT-PUBREPO (2026-10-28): the ONE box feeds an already-laid estate its keys again.
pub mod product_order;
pub mod refeed;
// OX-WGDS3 (2026-10-28): the operator's audited call on a laid site's console, through its
// public front, with the custody's break-glass bearer.
/// **A kit-installed operator site ADOPTED by the ONE box** (owner 2026-10-17): the run an update needs.
pub mod adopt;
/// A product guest's own lifecycle (`lifecycle.facts` / `lifecycle.lay_plan`, 2026-10-17).
pub mod guest_lifecycle;
/// **ONE lifecycle per product kind**: lay, update/upgrade, terminate, sale check.
pub mod lifecycle;
/// **One box laid again** for the estate guardian (5.4): the same lay + installer path.
pub mod relay;
/// The setup's own log in monetize: phases and the installer's lines, kept and published.
pub mod setup_log;
/// **A sold estate grows through its shop** (one shop, 2026-10-07): the
/// growth go-ahead signed once a data step is paid, and `SoldEstate`'s
/// calls, signed by the estate's client key.
pub mod sold;
/// The ONE box updates the estates and sites it laid (owner 2026-10-14, point 3).
pub mod update;
/// **Why `company` is a product's own name** (MONETIZE-FIX step 5, OM-12): the kind being sold
/// and every product this box links (its id and its family) are never sold as a company. The
/// names come from the registry, never from a list in the core.
pub fn product_name_refusal(state: &AppState, company: &str, kind: &str) -> Option<String> {
    let ids = state.registry.product_ids();
    let own = std::iter::once(kind)
        .chain(ids.iter().copied())
        .chain(ids.iter().map(|id| lifecycle::family_of(id)))
        .any(|n| !n.is_empty() && n == company);
    own.then(|| format!("{company:?} is a product's own name and is not sold as a company"))
}

/// **CODE RED** (owner 2026-10-18): what an automatic step left down, on every console page.
pub mod code_red;
/// Why an install makes no progress, by name; a CODE RED at 20 minutes (test3-holger-rs 2026-10-22).
pub mod install_why;
/// DEV-NARRATE on the ONE box: a narrated test site's boot logs, heard and kept (lane N2).
pub mod narrate;
/// The Overview's New-estate slot: a site made and handed to the one site order (OVW-CLEAN).
pub mod new_estate;
/// Closing a vendor's payment page, never blind (F-S-02/03, A17).
pub mod pages;
/// A refund or a dispute at the vendor on an estate's sale (F-S-01, A17).
pub mod reversed;
/// The estates that exist, classified for the Overview (OVW-CLEAN).
pub mod standing;

pub use domain::{CustomerRecord, DomainCheck, FileResolver, NoResolver};
pub use ladder::{
    charge_words, default_ladder, ladder, monthly_words, resources_words, sells_kept, sells_now,
    sells_refresh, total_words, Ladder, LadderStep, PricedStep, SELLS_FRESH_MS,
};
pub use price::{EstateSizes, Quote};
pub use term::{cancel, renew, Cancelled, Renewal, RenewalDone, TermPolicy};

/// The phase words, exactly as `EstateOrderStatusResponse.phase` carries them.
pub mod phase {
    pub const ORDERED: &str = "ordered";
    pub const HELD: &str = "held";
    /// A customer's own domain: waiting for their CNAME and proof (no slot held).
    pub const WAITING_DNS: &str = "waiting_dns";
    pub const LAYING: &str = "laying";
    pub const INSTALLING: &str = "installing";
    pub const PAIRED: &str = "paired";
    pub const CAPTURED: &str = "captured";
    pub const FAILED: &str = "failed";
    pub const RELEASED: &str = "released";
    /// The paid period ended unpaid; the estate still runs (`term`).
    pub const GRACE: &str = "grace";
    /// Unpaid past the grace: every server stopped, every disk kept.
    pub const SUSPENDED: &str = "suspended";
    /// Unpaid past the notice: being given back.
    pub const DELETING: &str = "deleting";
    /// Given back after the notice; the name is free.
    pub const DELETED: &str = "deleted";
    /// **Paid, and it could not be set up** ([`super::PAID_RETRIES`] times):
    /// everything laid was given back, the money is kept, and an operator
    /// retries it or cancels it with a refund (A23). Not driven; not free.
    pub const OWED: &str = "owed";
    /// Cancelled by the operator and its money refunded; the name is free.
    pub const REFUNDED: &str = "refunded";
    /// **TERMINATE asked by its account** (owner 2026-10-12): being given back, step by step.
    pub const TERMINATING: &str = "terminating";
    /// Terminated by its account: machines, disks, records gone; the name is free.
    pub const TERMINATED: &str = "terminated";

    /// A phase the driver still has work in.
    pub fn is_open(p: &str) -> bool {
        matches!(
            p,
            ORDERED | HELD | WAITING_DNS | LAYING | INSTALLING | PAIRED | FAILED | TERMINATING
        ) || is_term(p)
    }
    /// The phases of a delivered estate, driven by `term`.
    pub fn is_term(p: &str) -> bool {
        matches!(p, CAPTURED | GRACE | SUSPENDED | DELETING)
    }
    /// Nothing stands under the name any more: it may be ordered again.
    pub fn is_gone(p: &str) -> bool {
        matches!(p, RELEASED | DELETED | REFUNDED | TERMINATED)
    }
    /// The phases that hold a slot: something is being bought or built.
    pub fn holds_a_slot(p: &str) -> bool {
        matches!(p, LAYING | INSTALLING | PAIRED)
    }
}

// ── the configuration ───────────────────────────────────────────────────────

/// **`[estate_orders]`** in monetize.toml — present only on a monetize that
/// sells private estates (gunnar.rs's own). Absent: `EstateOrder.Start` is
/// refused by name and nothing here runs.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
#[serde(default)]
pub struct EstateOrderConfig {
    /// **The product a sold estate IS** (G8; OM-4, the owner 2026-10-10): the
    /// key its growth go-aheads and its facts are signed with, the fleet lane
    /// its boxes call in on, and the product its accounts and room are booked
    /// under — never a hard-coded "gunnar" (test2's sold estates would book
    /// under PROD gunnar's). Unset: the one `[pricing.<product>]` on this box
    /// is it; unset on a box that prices several (or none), the start is
    /// refused by name ([`EstateOrders::from_config_with`]).
    #[serde(default)]
    pub product: String,
    /// **The product KIND whose [`lifecycle::EstateLifecycle`] a sold estate follows**: the
    /// `[products.<product>] plugin` when it names one ([`EstateOrders::from_config_with`]);
    /// empty, the product id itself, else its family (`gunnar-test2` → `gunnar`).
    #[serde(skip)]
    pub lifecycle: String,
    /// The cloud the estate is laid at (`[clouds.<name>]`).
    pub cloud: String,
    /// The vendor the hold is taken with (`[vendors.<name>]`).
    pub vendor: String,
    /// The serving estate's apex: an order for `acme` is `acme.<apex>`.
    pub apex: String,
    /// The currency the estate is SOLD in — the provider's own, `EUR` for
    /// UpCloud (owner, 2026-10-04 19:45): no exchange rate in this code; the
    /// buyer sees SEK/DKK through Stripe's Adaptive Pricing.
    pub currency: String,
    /// **The margin over the provider's cost**, basis points: 2000 = 20 %.
    pub margin_bp: u32,
    /// **The floor at the buy**: a quoted price that would leave less than
    /// this over the provider's price NOW is not bought. 1000 = 10 %.
    pub min_margin_bp: u32,
    /// **The minimum term, prepaid**: the hold is this many months' price.
    pub term_months: u32,
    /// **A term of DAYS instead** (test2, the owner 2026-10-08: one day, so a real purchase
    /// is cheap to repeat): when set, the hold is the monthly price pro rata — `monthly ×
    /// days / 30`, rounded up — and the paid period this many days; `term_months` is then
    /// not used. 0: the term is `term_months`.
    #[serde(default)]
    pub term_days: u32,
    /// The provider's plans offered for front and main (empty: every plan
    /// the provider lists).
    pub plans: Vec<String>,
    /// How long a customer's own domain may take to point at us (and prove it).
    pub dns_wait_secs: u64,
    /// How a customer's domain is read: `file:<path>` (the mock's world DNS)
    /// or empty (no resolver: customer domains are refused at `Start`).
    pub resolver: String,
    /// At most this many estates are laid or installed at once.
    pub max_open: usize,
    /// At most this many private estates exist (delivered or in progress).
    pub max_estates: usize,
    /// An unpaid payment page is given up after this long.
    pub order_ttl_secs: u64,
    /// From the hold, the estate must answer within this long, or the job
    /// fails and the hold is released (an install takes about 35 minutes).
    pub capture_within_secs: u64,
    /// **The install deadline** (`[estate_orders] install_deadline_mins`, lane F2 2026-10-20:
    /// test3-holger-rs stood "installing" for a day, its twin retrying certify every 3 s): an
    /// order that stays in `installing` this many minutes without every box PAIRED is FAILED,
    /// its reason the installer's last pair status word for word. 0: no deadline.
    pub install_deadline_mins: u64,
    /// **How long a STOPPED operator-site install keeps its boxes** (`[estate_orders]
    /// failed_site_keep_hours`, MAP-SEG 3, owner 2026-10-26: "an abandoned or failed lay must
    /// remove its disks" — 18 storages no order owned, billed). Abandoned by the operator or
    /// failed by the install deadline, the site waits this long for its operator ("Check again"
    /// adopts boxes that paired since, F5; Terminate ends it now); then the box gives back every
    /// machine, disk, release clone and DNS name it laid, by itself, and the site can be ordered
    /// again. A protected site is never given back by itself. 0: given back at once.
    pub failed_site_keep_hours: u64,
    /// The vendor keeps a card authorisation about 7 days; the job never
    /// runs past this many seconds after the hold, whatever
    /// `capture_within_secs` says.
    pub hold_window_secs: u64,
    /// **REMOVED** (no-dwarf step 8, the owner 2026-10-08: "DWARFS MUST NOT BE INVOLVED!"):
    /// workers that pulled the install through the `EstateInstall` door. A shop pairs what it
    /// sells itself (`pairing`); a config that still names a worker is refused at start, by
    /// name, rather than ignored.
    pub install_workers: BTreeMap<String, String>,
    /// **The shop pairs the estate itself** (`pairing = "<name>"`, no operator machine in a
    /// sale, 2026-10-08): the installer a build LINKS under that name
    /// ([`crate::registry::Linked::installer`]; gunnar's front links `ShopPairing`). A build
    /// that links none of that name refuses to start, by name. (The kit as an `installer` argv, the
    /// one process monetize spawned, went in v2.0 step 1: a shop pairs, or it does not sell.)
    #[serde(default)]
    pub pairing: String,
    /// **The sold front's static feed** (`[estate_orders.sale_feed]`, rendered by the kit for
    /// the SELLING shop): key → value with `{{COMPANY}}`, `{{HOST}}`, `{{APEX}}` filled per
    /// order by the shop's own pairing. Never a shop credential (the pairing refuses one).
    #[serde(default)]
    pub sale_feed: BTreeMap<String, String>,
    /// **The release media a sold estate is laid from** (`[estate_orders.media]`, no-dwarf
    /// steps 3/4, 2026-10-08): kind (`front`, `gunnar`) → the provider's storage uuid of that
    /// kind's SEEDLESS release medium, uploaded once per release, never per sale. Each
    /// machine's medium is CLONED from its kind's at the lay; its seed reaches it as user_data.
    /// Required with `pairing` (a machine with no medium boots nothing).
    #[serde(default)]
    pub media: BTreeMap<String, String>,
    /// **The release media as OBJECTS** (`[estate_orders.media_objects.<kind>]`, owner
    /// 2026-10-09: the release ISO media live in UpCloud Object Storage): kind → `{url, sha256,
    /// bytes}`. A kind with no storage in [`Self::media`] is laid from its object: the provider
    /// imports it (once per release and zone) and clones it per machine. With the custody's
    /// `media.objsto` credential the shop PRESIGNS the url for each lay (an hour); without it
    /// the url is used as it is (a public object).
    #[serde(default)]
    pub media_objects: BTreeMap<String, monetize_cloud::lay::MediaObject>,
    /// **The release's TEMPLATES** (`[estate_orders.templates.<kind>]`, owner 2026-10-12,
    /// option (a)): kind → `{uuid, for_release}` — a provider template made from that kind's
    /// seedless release medium's installed disk (`cargo xtask estate release-template`). A
    /// machine is laid from its kind's template ONLY while `for_release` is the release the
    /// shop sells now ([`release_id`]); a stale one is passed over and the medium path stays.
    #[serde(default)]
    pub templates: BTreeMap<String, ReleaseTemplate>,
    /// **The release's LIVE apps** (`[estate_orders.live_apps.<kind>]`, owner 2026-10-14): kind
    /// (`gunnar`, `front`) → korp's live record of that kind's medium (its BASE, the app's pin,
    /// length, signature); the archive is the media object `<kind>-live`. What an update
    /// stages live on a box that runs the same BASE ([`update`]).
    #[serde(default)]
    pub live_apps: BTreeMap<String, update::LiveRecord>,
    /// **What each release IS, for a person** (`[estate_orders.release_notes."<release id>"]`,
    /// 2026-10-17): its label, when it was built and the commits it carries — written by the
    /// kit beside the media it publishes; the Sites page names a release by it, never by a hash.
    #[serde(default)]
    pub release_notes: BTreeMap<String, update::ReleaseNote>,
    /// **The operator site these terms lay ITSELF** (an operator-site order, owner 2026-10-13):
    /// the estate label whose host IS the apex (`gunnar-rs` → `gunnar.rs`), set by
    /// [`terms_of`] for such a run and never read from a file. Empty: every name is
    /// `<company>.<apex>`.
    #[serde(skip)]
    pub site_itself: String,
    /// ★ **A price these terms HOLD** (A33-5; the operator's own buy, owner 2026-10-12), minor
    /// units a term (and a month); 0: priced from the provider at the margin, held to the floor.
    /// Set by [`priced_for`], never read from a file: the one quote answers a held price as it
    /// is, and the one lay's recheck reads the provider's price for the cap and the laid cost.
    #[serde(skip)]
    pub held_price_minor: u64,
    /// **The ONE box's public IPv4, DEV-NARRATE's only source** (lane N2, 2026-10-20): fed as
    /// `[estate_orders] narrate_from`. The estate of a site that says `[estates.<label>]
    /// narrate = true` is laid (and its firewall written again) admitting udp/51822 from this
    /// address alone, and the shop's narrate job ([`narrate`]) listens to its boxes. Empty: no
    /// estate here is narrated, whatever a site says.
    pub narrate_from: String,
    /// **These terms narrate the estate they lay** — set by [`terms_of`] for the site order of
    /// a site that says `narrate = true`, never read from a file: a sold estate, and any site
    /// that does not say so, is laid with udp/51822 closed.
    #[serde(skip)]
    pub narrating: bool,
    /// **The bench's `fleet-feed-late`** (lane GATE, 2026-10-20): seconds the shop's pairing
    /// holds `fleet`, `fleet_instance` and `fleet_at` back from every box's first feed (fed in a
    /// later one, before the install closes — nordisk-pairing `installer.late_feed`). 0: fed at
    /// once. A MOCK knob: the kit renders it only for a `--where kvm` bench box.
    pub bench_fleet_late_s: u64,
    /// **The bench keeps an estate's secrets after its hand-off** (lane OX-WGDS3, 2026-10-28):
    /// the bench's downstream leg keeps the custody's material after the site is ready. The hand-off's forgetting is skipped, said once in the run's history. A
    /// MOCK knob: the kit renders it only for a `--where kvm` bench box.
    pub bench_keep_secrets: bool,
    /// **The installer's WireGuard link carries a pre-shared key** (lane WG-PSK-3, 2026-10-30;
    /// nordisk-pairing 0.5.29): every new order's seeds and link file get one, minted with the
    /// link's keys. OFF by default until every release this box sells reads it: a medium from
    /// before 0.5.29 ignores the seed's PSK and could never be reached over a link that has one.
    /// The switch: both products' media on nordisk-pairing >= 0.5.29 first, then
    /// `installer_link_psk = true` here (WG-PSK-3 handback). Orders laid before keep their seeds.
    pub installer_link_psk: bool,
    /// **The install's budget, seconds**: the shop's pairing closes the install within it
    /// (`monetize-shop-pairing`, at least 600); the fast test sets it low.
    pub installer_timeout_secs: u64,
    /// Where the job writes the estate's DNS records: `file:<path>` (the
    /// mock's recording writer) or empty (no writer here: the names are
    /// listed in the run and written by nobody).
    pub dns: String,
    pub zone: String,
    /// Labels every resource carries beside the reference and its role.
    pub labels: BTreeMap<String, String>,
    /// `[estate_orders.shape]` as the file names it; absent, the product's lifecycle's
    /// ([`lifecycle::Lifecycle::default_shape`]) at the start.
    #[serde(rename = "shape", default, skip_serializing_if = "Option::is_none")]
    pub shape_given: Option<Shape>,
    /// The shape the estates are laid and priced at: [`Self::shape_given`], else the lifecycle's.
    #[serde(skip)]
    pub shape: Shape,
    /// **The spend cap per estate**: at most this much a month at the
    /// provider, in its currency (EUR minor). Fixed on each run at its order;
    /// a quote, a lay, a renewal or a plan change over it is refused, and the
    /// estate's own monetize may grow by what is left under it.
    pub spend_cap_monthly_minor: u64,
    /// The term's rules: reminders, the grace, the stop, the deletion.
    pub term: TermPolicy,
    /// **The DNS writer's settings** (`[estate_orders.dns_settings]`) — what
    /// is not secret (an API base for a test's fake). The zone and the token
    /// are the custodian's (`--custody-credential dns.<writer>`).
    pub dns_settings: serde_json::Value,
    /// **The twin's autoscale rule** (`[estate_orders.twin]`): the marks, the
    /// hysteresis, the trend, the spacing, how often it is sampled.
    pub twin: twin::TwinRule,
    /// **The payment vendor's fee**, counted as COST by the floor at the buy
    /// (the 10 % is what is left after it): a fixed part per charge (minor
    /// units) and a percentage (basis points). The defaults are monetize's
    /// own rule for room (`monetize::pricing::PriceRule`: Stripe 0.25 + 1.5 %).
    pub fee_fixed_minor: u64,
    pub fee_bp: u32,
    /// **REMOVED (G12, 2026-10-10)**: the twin's lag and load were read by RUNNING the kit
    /// (`cargo xtask … estate twin-health`). They are read natively now, from the estate's own
    /// reports on the pull channel ([`twin::ReportedTwinHealth`]); a config that still names a command here
    /// is refused at start ([`TWIN_HEALTH_COMMAND_REMOVED`]). Kept only to refuse it by name.
    pub twin_health: Vec<String>,
    /// **The size ladder** (`[[estate_orders.ladder]]`): the named steps the
    /// sign-up page's one − / + moves through, smallest first. Absent: the
    /// default ladder, Mini (the tested shape) to Gigantic ([`ladder`]).
    pub ladder: Vec<LadderStep>,
    /// **How long the buyer's first-login link lives**, seconds (private
    /// ownership, 2026-10-07; default seven days): the kit records the invite
    /// at gunnar with this lifetime (`operator_invite_ttl_secs`), and the
    /// "ready" mail says it. Single use either way.
    pub first_login_ttl_secs: u64,
    /// **The door a sold estate calls the ONE monetize through** (ONE
    /// monetize, owner 2026-10-10: no estate runs a monetize, a sold one
    /// included): an https URL naming the one box, per product
    /// (`https://<product>.monetize.ignalina.dk` in ops config). **Config
    /// only** (G14): no default is made up in code (never the shop's web
    /// address `monetize.<apex>`) — an `[estate_orders]` without it is
    /// refused at start ([`EstateOrderConfig::shop_door`]). Handed to the kit
    /// in `laid.json` with this monetize's public key.
    pub shop_door: String,
    /// **How long a sold estate is told before its machines stop** (one shop
    /// 4, 2026-10-07; default 60 s): a paid plan change waits this long in
    /// `queued`, so the estate's console can say it is down for maintenance rather than
    /// "not responding".
    pub resize_notice_secs: u64,
    /// **Company names this shop never sells** (`reserved_names`; A44,
    /// 2026-10-08): the kit names here the operator's own estates its
    /// `estate.toml` declares (`test1`, `speed`, …) — an order for one is
    /// answered "taken" before any money moves.
    pub reserved_names: Vec<String>,
}

/// **The estate's three machines**, as templates over `{company}`. The
/// defaults are the kit's own declaration (`private-gunnar-ops/terraform`,
/// `estate.auto.tfvars.json` and an instance's `-<company>` suffix), so what
/// monetize lays is what the kit's `--laid` adopts without a change.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct Shape {
    pub front: MachineShape,
    pub main: MachineShape,
    pub twin: MachineShape,
    /// **The product's own floor for its twin's memory**, MiB (owner 2026-10-23: Holger's twin
    /// is a 1 GB box). Absent: 4 GiB, gunnar-server's floor ([`monetize_cloud::lay::TWIN_FLOOR_MEMORY_MIB`]).
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub twin_floor_mib: Option<u64>,
}

#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct MachineShape {
    pub hostname: String,
    pub title: String,
    pub plan: String,
    #[serde(default = "disk_cdrom")]
    pub boot_order: String,
    /// The `role` label the kit's declaration stamps (`front` | `appliance` | `twin`).
    pub role_label: String,
    pub disks: Vec<DiskShape>,
    /// Its network interfaces — laid and PRICED (each public IPv4 is billed).
    /// Absent: a public and a utility IPv4, as the kit declares every box.
    #[serde(default = "monetize_cloud::lay::default_interfaces")]
    pub interfaces: Vec<monetize_cloud::lay::NetInterface>,
}

#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct DiskShape {
    pub title: String,
    pub gib: u64,
    pub tier: String,
    /// The `volume` label (`system` | `data1` … | `twin`).
    pub volume: String,
}

fn disk_cdrom() -> String {
    "disk,cdrom".into()
}

/// **A shape's default is a Mini estate of three machines** — a 2-core 4 GB front, a 4-core
/// 8 GB main with four 10 GB data disks, a 1-core 4 GB twin — what a config built in code that
/// names no shape is laid and PRICED at, named by role alone (`front-{company}`, …): it names
/// no product (v2.0 P3). A config READ from a file that names no `[estate_orders.shape]` takes
/// its product's lifecycle's (its guest's, [`lifecycle::Lifecycle::default_shape`]) at the
/// start ([`EstateOrders::from_config_with`]); a product whose plan names its own machines (the
/// Lake) is laid by its plan.
impl Default for Shape {
    fn default() -> Self {
        let d = |title: &str, gib, tier: &str, volume: &str| DiskShape {
            title: title.into(),
            gib,
            tier: tier.into(),
            volume: volume.into(),
        };
        let boot = disk_cdrom;
        Shape {
            front: MachineShape {
                hostname: "front-{company}".into(),
                title: "the front — the web, the console, the relay-{company}".into(),
                plan: "STARTER-2xCPU-4GB".into(),
                boot_order: boot(),
                role_label: "front".into(),
                disks: vec![d("front-{company} system", 40, "standard", "system")],
                interfaces: monetize_cloud::lay::default_interfaces(),
            },
            main: MachineShape {
                hostname: "main-{company}".into(),
                title: "the main — the primary, no shell-{company}".into(),
                plan: "STARTER-4xCPU-8GB".into(),
                boot_order: boot(),
                role_label: "appliance".into(),
                disks: vec![
                    d("main-{company} system", 50, "standard", "system"),
                    d("main-{company} data 1", 10, "maxiops", "data1"),
                    d("main-{company} data 2", 10, "maxiops", "data2"),
                    d("main-{company} data 3", 10, "maxiops", "data3"),
                    d("main-{company} data 4", 10, "maxiops", "data4"),
                ],
                interfaces: monetize_cloud::lay::default_interfaces(),
            },
            twin: MachineShape {
                hostname: "twin-{company}".into(),
                title: "the twin — the log-holder, no shell-{company}".into(),
                plan: "STARTER-1xCPU-4GB".into(),
                boot_order: boot(),
                role_label: "twin".into(),
                disks: vec![
                    d("twin-{company} system", 20, "standard", "system"),
                    d("twin-{company} data", 20, "hdd", "twin"),
                ],
                interfaces: monetize_cloud::lay::default_interfaces(),
            },
            twin_floor_mib: None,
        }
    }
}

impl Default for EstateOrderConfig {
    fn default() -> Self {
        EstateOrderConfig {
            product: String::new(),
            lifecycle: String::new(),
            cloud: "upcloud".into(),
            // ★ ST-5: never made up — a site's own account and apex ([`terms_on`]), else
            // the ones configured; neither set is refused by name.
            vendor: String::new(),
            apex: String::new(),
            currency: "EUR".into(),
            margin_bp: 2_000,
            min_margin_bp: 1_000,
            term_months: 6,
            term_days: 0,
            plans: Vec::new(),
            dns_wait_secs: 48 * 3_600,
            resolver: String::new(),
            max_open: 2,
            max_estates: 10,
            order_ttl_secs: 3_600,
            capture_within_secs: 86_400,
            install_deadline_mins: 60,
            failed_site_keep_hours: 24,
            hold_window_secs: 6 * 86_400,
            install_workers: BTreeMap::new(),
            pairing: String::new(),
            sale_feed: BTreeMap::new(),
            media: BTreeMap::new(),
            media_objects: BTreeMap::new(),
            templates: BTreeMap::new(),
            live_apps: BTreeMap::new(),
            release_notes: BTreeMap::new(),
            site_itself: String::new(),
            held_price_minor: 0,
            narrate_from: String::new(),
            narrating: false,
            bench_fleet_late_s: 0,
            bench_keep_secrets: false,
            installer_link_psk: false,
            installer_timeout_secs: 3 * 3_600,
            dns: String::new(),
            zone: "se-sto1".into(),
            labels: BTreeMap::new(),
            shape_given: None,
            shape: Shape::default(),
            spend_cap_monthly_minor: 200_000,
            term: TermPolicy::default(),
            dns_settings: serde_json::Value::Null,
            fee_fixed_minor: monetize::pricing::PriceRule::default().fee_fixed_minor,
            fee_bp: monetize::pricing::PriceRule::default().fee_bp,
            twin: twin::TwinRule::default(),
            twin_health: Vec::new(),
            ladder: default_ladder(),
            first_login_ttl_secs: 7 * 86_400,
            shop_door: String::new(),
            resize_notice_secs: 60,
            reserved_names: Vec::new(),
        }
    }
}

impl EstateOrderConfig {
    /// [`Self::product`], named or derived at the start
    /// ([`EstateOrders::from_config_with`]). Empty — a config that never went
    /// through the start — is refused by name, never answered "gunnar".
    pub fn sold_product(&self) -> Result<&str, String> {
        let p = self.product.trim();
        if p.is_empty() {
            return Err(
                "[estate_orders] product is not set: name the product a sold estate is".into(),
            );
        }
        Ok(p)
    }

    /// **The first-login link's lifetime**, seconds: the configured one held
    /// to an hour at least and 30 days at most (gunnar keeps no invite longer).
    pub fn first_login_ttl(&self) -> u64 {
        self.first_login_ttl_secs.clamp(3_600, 30 * 86_400)
    }

    /// The estate's names: `<company>.<apex>` — the ONE naming both the
    /// shop and the kit call ([`monetize_embed::sold::SoldNames`], A43).
    pub fn host_of(&self, company: &str) -> String {
        if self.is_site_itself(company) {
            return self.apex.trim().trim_end_matches('.').to_ascii_lowercase();
        }
        monetize_embed::sold::SoldNames::of(company, &self.apex).host
    }

    /// **Where the estate these terms lay takes DEV-NARRATE knocks from**: the ONE box's
    /// [`Self::narrate_from`] when these terms narrate it ([`Self::narrating`]), else empty
    /// (udp/51822 stays closed).
    pub fn narrate_source(&self) -> &str {
        if self.narrating {
            self.narrate_from.trim()
        } else {
            ""
        }
    }

    /// Whether `company` is the operator site these terms lay itself ([`Self::site_itself`]).
    pub fn is_site_itself(&self, company: &str) -> bool {
        !self.site_itself.is_empty() && self.site_itself == company
    }

    /// **Every name the estate serves**: its host and the names its product's lifecycle serves
    /// beside it (Gunnar's and Holger's: `www.` and `git.`) — under the shop's apex for a sold
    /// estate, the apex's own for an operator site laid itself. A product with no lifecycle here:
    /// Gunnar's three, as before.
    pub fn names_of(&self, company: &str) -> Vec<String> {
        let host = self.host_of(company);
        let prefixes = lifecycle::of(self)
            .map(|l| l.served_prefixes())
            .unwrap_or_else(|_| vec![String::new(), "www.".into(), "git.".into()]);
        prefixes.iter().map(|p| format!("{p}{host}")).collect()
    }

    /// **The estate's DNS records**: [`records_for`] — a sold estate never takes the serving
    /// estate's own names — or, for the operator site laid itself, exactly those names.
    pub fn records_of(&self, company: &str, front_ipv4: &str) -> Result<Vec<DnsRecord>, String> {
        if self.is_site_itself(company) {
            return Ok(self
                .names_of(company)
                .into_iter()
                .map(|name| DnsRecord {
                    name,
                    kind: "A".into(),
                    value: front_ipv4.into(),
                    proxied: false,
                })
                .collect());
        }
        // The sold names its product serves (A17: no `git.` for a product that serves none; the
        // Lake's `s3.`, which Gunnar's set never had), each refused when it is the serving
        // estate's own, as [`records_for`] refuses them.
        // HOL-REPO-NAME: and every name the product serves under the apex (Holger's `repo.`):
        // a buyer called `repo` never takes the site's repository name.
        let own = lifecycle::of(self)
            .map(|l| l.served_prefixes())
            .unwrap_or_default();
        let serving: BTreeSet<String> = ["", "www.", "git.", "monetize."]
            .iter()
            .map(|p| p.to_string())
            .chain(own)
            .map(|p| format!("{p}{}", self.apex))
            .collect();
        self.names_of(company)
            .into_iter()
            .map(|name| {
                if serving.contains(&name) {
                    Err(format!(
                        "the record {name} is the serving estate's own name; nothing was written"
                    ))
                } else {
                    Ok(DnsRecord {
                        name,
                        kind: "A".into(),
                        value: front_ipv4.into(),
                        proxied: false,
                    })
                }
            })
            .collect()
    }

    /// **The configured shop door** (one monetize, G14 2026-10-10): the
    /// configured `https://<host>`, trimmed and without a trailing `/` —
    /// refused by name when absent or not an https URL with a host. Nothing is
    /// made up from the apex: the one monetize is not the shop's web address.
    pub fn shop_door(&self) -> Result<String, String> {
        let door = self.shop_door.trim().trim_end_matches('/');
        if door.is_empty() {
            return Err("[estate_orders] shop_door is not set: name the https door sold estates call the one monetize through".into());
        }
        let host = door.strip_prefix("https://").unwrap_or("");
        if host.is_empty() || door.chars().any(char::is_whitespace) {
            return Err(format!(
                "[estate_orders] shop_door = {door:?} is not an https URL with a host"
            ));
        }
        Ok(door.to_string())
    }
}

/// **The plan `lay_estate` is asked for**: the shape with `{company}` filled in, every resource
/// labelled with its role (and a disk with its volume), each role's system disk in the tier of
/// ITS medium kind's template (`life`'s [`lifecycle::Lifecycle::medium_kind`]: Holger's
/// front reads `holger-front`'s).
pub fn plan_for_as(
    cfg: &EstateOrderConfig,
    company: &str,
    sizes: &EstateSizes,
    twin_plan: &str,
    life: &lifecycle::Lifecycle,
) -> EstatePlan {
    plan_for_by(cfg, company, sizes, twin_plan, &|role| {
        life.medium_kind(role)
    })
}

fn plan_for_by(
    cfg: &EstateOrderConfig,
    company: &str,
    sizes: &EstateSizes,
    twin_plan: &str,
    kind_of: &dyn Fn(&str) -> String,
) -> EstatePlan {
    let fill = |t: &str| t.replace("{company}", company);
    let or = |asked: &str, shape: &str| {
        if asked.trim().is_empty() {
            shape.to_string()
        } else {
            asked.trim().to_string()
        }
    };
    let mut front = cfg.shape.front.clone();
    front.plan = or(&sizes.front_plan, &front.plan);
    let mut main = cfg.shape.main.clone();
    main.plan = or(&sizes.main_plan, &main.plan);
    if sizes.main_data_gib > 0 {
        main.disks
            .iter_mut()
            .skip(1)
            .for_each(|d| d.gib = sizes.main_data_gib);
    }
    // **The twin follows main** (owner, 2026-10-04): its plan is chosen from
    // main's, and its data disk holds main's whole data set.
    let mut twin = cfg.shape.twin.clone();
    if !twin_plan.is_empty() {
        twin.plan = twin_plan.to_string();
    }
    let main_data: u64 = main.disks.iter().skip(1).map(|d| d.gib).sum();
    if let Some(d) = twin.disks.get_mut(1) {
        d.gib = d.gib.max(main_data);
    }
    let machine = |role: &str, m: &MachineShape| {
        let mut labels = cfg.labels.clone();
        labels.insert("role".into(), m.role_label.clone());
        MachinePlan {
            role: role.into(),
            hostname: fill(&m.hostname),
            title: fill(&m.title),
            plan: m.plan.clone(),
            boot_order: m.boot_order.clone(),
            labels: labels.clone(),
            interfaces: m.interfaces.clone(),
            // The release medium and the seed are the sale's (no-dwarf step 4): set where the
            // lay is called, never kept with the plan.
            medium: String::new(),
            medium_object: None,
            template: String::new(),
            user_data: Default::default(),
            disks: m
                .disks
                .iter()
                .map(|d| {
                    let mut l = labels.clone();
                    l.insert("volume".into(), d.volume.clone());
                    // A system disk cloned from the release's template is laid in the TEMPLATE's
                    // tier (UpCloud: a custom template deploys only in its own tier, and only
                    // maxiops is templatized — live 409 STORAGE_TIER_ILLEGAL, 2026-10-14), and
                    // priced so: the quote, the buy-time recheck and the lay read this one plan.
                    let tier = match template_of(cfg, &kind_of(role)) {
                        Some(t) if d.volume == "system" => t.tier().to_string(),
                        _ => d.tier.clone(),
                    };
                    DiskPlan {
                        title: fill(&d.title),
                        gib: d.gib,
                        tier,
                        labels: l,
                    }
                })
                .collect(),
        }
    };
    EstatePlan {
        reference: reference_of(company),
        company: company.into(),
        zone: Zone(cfg.zone.clone()),
        machines: vec![
            machine("front", &front),
            machine("main", &main),
            machine("twin", &twin),
        ],
        narrate_from: cfg.narrate_source().to_string(),
        shape: None,
    }
}

// ── the run ─────────────────────────────────────────────────────────────────

/// One transition, as the run keeps it.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct Transition {
    pub phase: String,
    pub at_ms: u64,
    pub note: String,
}

/// **One order, as its file holds it.** No secret is ever in here.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct EstateRun {
    pub company: String,
    pub reference: String,
    /// Where the "ready" / "failed" mail goes. Never logged.
    pub email: String,
    /// **The SITE it was bought on** (ST-5, ONE monetize 2026-10-11): the calling estate's
    /// label (`test2-gunnar-rs`). Its money, its name (`<company>.<site>`) and its renewals
    /// are that site's ([`terms_of`]). Empty: an order from before sites, the product's home.
    #[serde(default)]
    pub estate: String,
    /// **Whose Gunnar it is**: the account name its first admin is to have,
    /// as the sign-up page sent it (`EstateOrderStartRequest.account`); the
    /// installer is told it as `{account}`, and the "ready" mail's first-login
    /// link registers its first passkey. Never empty: it is also the tenant
    /// of the order's `Instance` row on the gunnar ledger (G5), so a run
    /// without it is refused at the door and does not parse from disk.
    pub account: String,
    pub phase: String,
    pub ordered_at_ms: u64,
    /// When the vendor first said the money is held; 0 before.
    pub held_at_ms: u64,
    /// What is held: the six months' price (`quote.total`).
    pub amount: Money,
    /// **The price as quoted** — sizes, the provider's cost, the rate, the
    /// margin, the term — the estate's own billing record.
    pub quote: Quote,
    /// The customer's own domain (`gunnar.company1.com`); empty: `<company>.<apex>` only.
    pub domain: String,
    /// The ownership proof the customer publishes (public, not a secret).
    pub proof: String,
    /// When the job started waiting for the customer's records; 0 before.
    pub dns_waiting_since_ms: u64,
    /// When the customer's records were found; 0 before (or no own domain).
    pub dns_verified_at_ms: u64,
    /// When the money was captured, and until when the term is paid.
    pub captured_at_ms: u64,
    pub paid_until_ms: u64,
    pub handle: Option<ChargeHandle>,
    pub checkout_url: String,
    pub laid: Option<LaidEstate>,
    pub dns: Vec<DnsRecord>,
    /// **The writer that wrote [`Self::dns`]**, by name (DNS-WRITER, 2026-10-26): its give-back
    /// removes them with THAT writer, wherever the site's writes now. Empty: a run from before
    /// (or a writer without a name): the site's writer of now.
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub dns_writer: String,
    /// **The product this run is** (PROD-FIX 2, prod 2026-10-26): its site's product at the
    /// order, kept, so a run whose site leaves the feed is still read as ITS product — never
    /// the shop's default. Empty: a run from before (its site's, else the fleet's record).
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub product: String,
    /// **Why the run is stopped by name, and when** (PROD-FIX 2): a final refusal of its terms
    /// (its site left the feed, or sells another product). A stopped run is neither booked nor
    /// driven; it is looked at again after [`STOPPED_LOOK_AGAIN_MS`], and resumes once its
    /// terms read again. Empty: not stopped.
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub stopped_why: String,
    #[serde(default)]
    pub stopped_at_ms: u64,
    /// The installer's verdict, as it wrote it.
    pub receipt: Option<serde_json::Value>,
    /// Why the job failed, or what it is waiting for now.
    pub why: String,
    pub history: Vec<Transition>,
    /// The "ready" / "failed" mail went out (or was refused, said in `history`).
    pub told: bool,
    /// The provider ids the give-back has already asked to go (servers).
    #[serde(default)]
    pub given_back: Vec<String>,
    /// **A terminate's give-back that failed, in a row** (F4): how many asks failed since the
    /// last one that moved, and when the tick asks the provider again (unix ms; 0: at once).
    #[serde(default)]
    pub give_back_failures: u32,
    #[serde(default)]
    pub give_back_retry_at_ms: u64,
    /// **The estate's WireGuard peer map** (public keys only), kept by the
    /// custodian for the control and custody link it will take (§11).
    #[serde(default)]
    pub peers: Vec<WgPeer>,
    /// What the estate costs a month at the provider, as read at the lay.
    #[serde(default = "no_cap")]
    pub laid_cost: Money,
    /// **The estate's spend cap**, fixed at the order (EUR a month at the provider).
    #[serde(default = "no_cap")]
    pub spend_cap: Money,
    /// The renewal the customer opened and has not paid yet.
    #[serde(default)]
    pub renewal: Option<Renewal>,
    /// Every renewal paid, in order.
    #[serde(default)]
    pub renewals: Vec<RenewalDone>,
    /// The reminders and warnings sent, once each: `<paid_until_ms>:<kind>:<day>`.
    #[serde(default)]
    pub reminded: Vec<String>,
    /// **The deletion date**, fixed by the first mail of a lapse; 0 while paid.
    #[serde(default)]
    pub delete_on_ms: u64,
    /// When the servers were stopped for non-payment; 0 while running.
    #[serde(default)]
    pub suspended_at_ms: u64,
    /// The servers stopped for non-payment, started again when it is paid.
    #[serde(default)]
    pub stopped: Vec<String>,
    /// **The plan change in flight**, if any (`change`).
    #[serde(default)]
    pub change: Option<change::PlanChange>,
    /// Every plan change finished (done or failed), in order.
    #[serde(default)]
    pub changes: Vec<change::PlanChange>,
    /// The twin's plan as it grew by itself (empty: an eighth of main's, the rule).
    #[serde(default)]
    pub twin_floor: String,
    /// When the twin last changed plan (the autoscale's cooldown).
    #[serde(default)]
    pub twin_changed_at_ms: u64,
    /// When the laid sizes were last read back from the provider
    /// ([`refresh_laid`]); 0 never.
    #[serde(default)]
    pub sizes_read_at_ms: u64,
    /// **The estate's client key, its public half** (64 hex; one shop,
    /// 2026-10-07): what this shop verifies the SOLD estate's
    /// calls under (`SoldEstate`). Read from custody at the install; empty for
    /// an estate installed before it existed, until its next install.
    #[serde(default)]
    pub client_key: String,
    /// **The growth go-ahead this shop signed** for the newest paid data step
    /// ([`sold::Growth`]); the estate's boxes pull it in a `grow_go_ahead` order.
    #[serde(default)]
    pub growth: Option<sold::Growth>,
    /// **Since when the order waits for the shop's cloud cap** (the owner,
    /// 2026-10-08: "the customer must not know about a cap! it must be queued
    /// and resized later"): 0 when it does not. While it waits the order stays
    /// `held` — the buyer reads "being prepared" — and the operator is told
    /// to raise the cap ([`ORDERS_WAIT`]). The job's own deadline does not run
    /// meanwhile; the vendor's hold window still does.
    #[serde(default)]
    pub cap_waiting_since_ms: u64,
    /// When the cap last admitted it after a wait: the job's deadline counts
    /// from here. 0: it never waited.
    #[serde(default)]
    pub cap_cleared_at_ms: u64,
    /// When a waiting order last asked the queue ([`QUEUE_LOOK_EVERY_MS`]).
    #[serde(default)]
    pub queue_looked_at_ms: u64,
    /// ★ A32-22: when the operator was last told that this PAID order waits in the queue too
    /// long ([`QUEUED_TELL_AFTER_MS`]); 0: never. The buyer then reads since when it waits and
    /// the day it is set up or refunded by.
    #[serde(default, skip_serializing_if = "is_zero_u64")]
    pub queue_told_at_ms: u64,
    /// ★ A32-22: when the operator was last told that this order is OWED ([`OWED_TELL_EVERY_MS`]).
    #[serde(default, skip_serializing_if = "is_zero_u64")]
    pub owed_told_at_ms: u64,
    /// What it waits for, in the operator's words (empty when it does not).
    #[serde(default)]
    pub queue_why: String,
    /// How often this PAID order failed and was given back ([`PAID_RETRIES`]).
    #[serde(default)]
    pub failures: u32,
    /// **When its buyer cancelled** (no renewal; [`term::cancel`]); 0: not.
    #[serde(default)]
    pub cancelled_at_ms: u64,
    /// When the "ready"/"failed" mail was last tried (A47: retried hourly until sent).
    #[serde(default)]
    pub told_tried_at_ms: u64,
    /// **When the shop forgot the estate's secrets** (the owner via the
    /// coordinator, 2026-10-08: after a PASSed hand-off the shop keeps only its
    /// own facts key and what reads health and billing — never a key that could
    /// open the buyer's data or backups). 0: not yet.
    #[serde(default)]
    pub secrets_forgotten_at_ms: u64,
    /// **When the release clones were given back** (no-dwarf step 4, 2026-10-08): once the
    /// estate is handed over, each machine's cdrom clone of the release medium is ejected and
    /// deleted (`Change::ForgetMedia`, journaled clones only). 0: not yet, or none.
    #[serde(default)]
    pub media_forgotten_at_ms: u64,
    /// **The release each box runs** (F4 sold upgrade, 2026-10-09): role → the release's
    /// identity ([`release_id`]), set at the lay and after each upgrade. A role absent ran
    /// whatever was laid before it was kept.
    #[serde(default)]
    pub release_of: BTreeMap<String, String>,
    /// **When the estate took its installer material** (F4, `SoldEstate.TakeMaterial`): the
    /// hand-off forgets the custody only after it ([`sold::material_waits`]). 0: not (yet).
    #[serde(default)]
    pub material_taken_at_ms: u64,
    /// When the buyer was last mailed a new sign-in link (S10); 0: never.
    #[serde(default)]
    pub sign_in_again_at_ms: u64,
    /// When the sale check last asked the public front (S4, [`SALE_CHECK_EVERY_MS`]); 0: never.
    #[serde(default)]
    pub sale_checked_at_ms: u64,
    /// When the ONE box last looked whether a silent PAIRED estate's boxes lack the fleet seam
    /// ([`SEAM_HEAL_EVERY_MS`], HRS-DIAG); 0: never.
    #[serde(default)]
    pub seam_looked_at_ms: u64,
    /// **Ordered by the operator's TEST BUTTON** (2026-10-11), or a `site test-order`
    /// ([`is_test_paid`]), paid with the vendor's test payment method: real machines, play
    /// money. What a console filters on.
    #[serde(default)]
    pub test: bool,
    /// **The operator's own buy** (owner 2026-10-12): ordered by the admin of one of the
    /// operator's OWN sites ([`crate::config::EstateConfig::operator_site`]) at
    /// [`OPERATOR_TEST_MINOR`], the margin floor not asked of it. Its ledger row says
    /// "operator test" and is never revenue.
    #[serde(default)]
    pub operator_test: bool,
    /// **An OPERATOR-SITE ORDER** (owner 2026-10-13): the ONE box lays the declared operator
    /// site [`EstateRun::estate`] (its `[estates.<label>]`) itself, under the site's own apex
    /// names; `company` is the label as the cloud names an estate ([`site::company_of`]).
    #[serde(default)]
    pub site_order: bool,
    /// The digest of the bearer the laid site's console was fed ([`crate::fleet::bearer_digest`]),
    /// when it was minted and until when it opens; restated at every tick ([`site::reassert`]).
    #[serde(default)]
    pub site_bearer_sha256: String,
    #[serde(default)]
    pub site_bearer_at_ms: u64,
    #[serde(default)]
    pub site_bearer_until_ms: u64,
    /// The ticket key the laid site's primary offered ([`InstallVerdict::ticket_key`]).
    #[serde(default)]
    pub site_ticket_key: String,
    /// The seed's PUBLIC key the order named ([`SiteFeed::seed_key`]); empty: none.
    #[serde(default)]
    pub site_seed_key: String,
    /// **The update in flight** (owner 2026-10-14: the ONE box updates what it laid), if any.
    #[serde(default)]
    pub update: Option<update::EstateUpdate>,
    /// Every update finished (done or failed), the newest [`update::KEEP_FINISHED`].
    #[serde(default)]
    pub updates: Vec<update::EstateUpdate>,
    /// **Live updates OFF for this estate** (a military customer): every box is updated from its
    /// keep medium only. Off unless the operator says so (`EstateOrder.SetLiveUpdate`).
    #[serde(default)]
    pub live_update_off: bool,
    /// **When the ONE box ADOPTED this kit-installed site** ([`adopt`], owner 2026-10-17); 0:
    /// laid here. An adopted run is updated by this box and NEVER laid, re-laid, fenced, given
    /// back or billed by it: its machines carry no label of this shop.
    #[serde(default)]
    pub adopted_at_ms: u64,
    /// **When the estate's front last asked for an update** (`SoldEstate.UpdateTake`, every 2 min
    /// on a front that carries the update taker; kept at most hourly); 0: never — its front runs a
    /// release with no taker, so an update of it goes FRONT FIRST ([`update::start`]).
    #[serde(default)]
    pub update_taken_at_ms: u64,
    /// ★ **The account this order makes when it is paid** (pay once, owner 2026-10-22): a
    /// visitor bought with no account yet; [`account::NewAccount`] is made at the payment, once
    /// (its session), and `account` is its name. `None`: a proven account's order (its ticket).
    #[serde(default, skip_serializing_if = "Option::is_none")]
    pub new_account: Option<account::NewAccount>,
    /// ★ **Money the vendor said went back on this estate's sales** (F-S-01, A17): its order's,
    /// its renewals' and its plan changes' refunds and disputes, once each ([`reversed`]).
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub reversals: Vec<reversed::EstateReversal>,
    /// **When a reversal took the paid time back** (all of a sale refunded, or a dispute lost);
    /// 0: none, or a renewal paid since. Such an estate goes the nonpay way — grace, then stopped
    /// with every disk kept — and is never DELETED by it: the operator decides.
    #[serde(default)]
    pub reversed_at_ms: u64,
    /// ★ **Payment pages the shop let go of that the vendor did not close** (F-S-02/03, A17):
    /// kept, said, and asked to close again on every tick ([`pages::look`]) — never dropped.
    #[serde(default, skip_serializing_if = "Vec::is_empty")]
    pub unreleased: Vec<pages::OpenPage>,
}

/// **What the operator's own buy costs** (owner 2026-10-12): EUR 0.50, the vendor's smallest
/// charge, held, laid and captured the normal way.
pub const OPERATOR_TEST_MINOR: u64 = 50;

/// Pure: **is this the operator's own buy?** — `account` (the plain name its site knows) is
/// the admin of `estate`, one of the operator's OWN sites. Never true without a site.
pub fn is_operator_buy(state: &AppState, estate: &str, account: &str) -> bool {
    let estate = estate.trim();
    !estate.is_empty()
        && state
            .registry
            .operator_admin_of(estate)
            .is_some_and(|admin| admin == account.trim())
}

/// Pure: ★ A33-5 — **the terms an order is priced on**: `cfg` itself, or, for the operator's
/// own buy ([`is_operator_buy`], kept as [`EstateRun::operator_test`]), the same terms HOLDING
/// [`OPERATOR_TEST_MINOR`] a term ([`EstateOrderConfig::held_price_minor`]) with no floor and no
/// fee share asked. Data the one quote ([`price::quote_as_laid`]) and the one lay's recheck
/// ([`price::recheck`]) read; neither branches on who pays.
pub fn priced_for(cfg: &EstateOrderConfig, operator: bool) -> EstateOrderConfig {
    if !operator {
        return cfg.clone();
    }
    EstateOrderConfig {
        held_price_minor: OPERATOR_TEST_MINOR,
        min_margin_bp: 0,
        fee_fixed_minor: 0,
        fee_bp: 0,
        ..cfg.clone()
    }
}

/// **The operator's words for an order the cloud's cap holds back**: in the
/// run's `why`, its history, the ALERT line and the functional status — never
/// in anything the buyer reads.
pub const ORDERS_WAIT: &str = "orders wait: raise the cap";

/// The operator's words for an order `max_estates` holds back (A09).
pub const ORDERS_WAIT_ESTATES: &str = "orders wait: raise max_estates";

fn no_cap() -> Money {
    Money {
        minor: 0,
        currency: monetize_pay::Currency::Eur,
    }
}

impl EstateRun {
    /// **The name its boxes pull as, and the guardian knows it by**: the company — or, for an
    /// operator site laid itself, the site's own label (`gunnar-rs`), the estate it already is.
    pub fn fleet_name(&self) -> &str {
        if self.site_order {
            &self.estate
        } else {
            &self.company
        }
    }

    /// **The canonical name of `host`** (WWW-CANON, owner 2026-10-30: the sites are
    /// `www.<site>`): `www.<host>` when this estate's lay named it (its DNS records), else
    /// `host`. The bare name stays the passkeys' relying party; every URL a buyer is given is
    /// on this one.
    pub fn canonical_host(&self, host: &str) -> String {
        let www = format!("www.{host}");
        if !host.starts_with("www.") && self.dns.iter().any(|d| d.name.eq_ignore_ascii_case(&www)) {
            www
        } else {
            host.to_string()
        }
    }

    /// **What the buyer is told**, the product called as `w` says.
    pub fn customer_view_as(
        &self,
        apex: &str,
        w: &lifecycle::ProductWords,
    ) -> (String, String, String) {
        let t = &w.title;
        let host = if self.site_order {
            apex.to_string()
        } else {
            format!("{}.{apex}", self.company)
        };
        let (state, words) = match self.phase.as_str() {
            phase::ORDERED => ("waiting_for_payment", "Waiting for your payment on the payment page.".to_string()),
            // ★ A32-22: a paid order that waits long reads since when, and the day it is set up or refunded by.
            phase::HELD if self.captured_at_ms > 0 && self.queue_told_at_ms > 0 => (
                "queued",
                format!(
                    "Your {t} is paid and waits for room to be set up (since {}); we are on it, and you get a mail when it runs. If it is not set up by {}, it is set up by the operator or refunded in full.",
                    iso_date(self.held_since_ms()),
                    iso_date(self.held_since_ms().saturating_add(QUEUED_DEADLINE_MS))
                ),
            ),
            phase::HELD if self.captured_at_ms > 0 => ("queued", format!("Your {t} is paid and being prepared.")),
            phase::HELD => ("queued", format!("Your payment is held, not charged. Your {t} is being prepared.")),
            phase::WAITING_DNS => (
                "waiting_for_dns",
                format!("{} Add the two records below at the DNS provider of {}; we look every minute.", if self.captured_at_ms > 0 { format!("Your {t} is paid.") } else { "Your payment is held, not charged.".to_string() }, self.domain),
            ),
            phase::LAYING => ("laying", "Your machines and disks are being set up.".to_string()),
            phase::INSTALLING | phase::PAIRED => ("installing", format!("{t} is being installed on your machines.")),
            phase::CAPTURED if self.site_order && self.adopted_at_ms > 0 => ("ready", format!("The site runs at https://{host}: installed by its kit, adopted by this box on {}, which updates it.", iso_date(self.adopted_at_ms))),
            phase::CAPTURED if self.site_order => ("ready", format!("The site is ready at https://{host}.{}", if self.account.is_empty() { "" } else if self.told { " Its first sign-in link was mailed." } else { " Its first sign-in link is being mailed." })),
            phase::CAPTURED => (
                "ready",
                format!(
                    "Your {t} is ready at https://{}; it is paid until {}.{}",
                    if self.domain.is_empty() { &host } else { &self.domain },
                    iso_date(self.paid_until_ms),
                    if self.account.is_empty() { "" } else if self.told { " Your first sign-in link was mailed to you." } else { " Your first sign-in link is being mailed to you." }
                ),
            ),
            phase::GRACE => ("overdue", format!("Your {t}'s paid period ended on {}. It still runs; renew to keep it running.", iso_date(self.paid_until_ms))),
            phase::SUSPENDED => (
                "suspended",
                if self.delete_on_ms > 0 {
                    format!("Your {t} is stopped; every disk and all your data are kept until {}. Renew and it starts again.", iso_date(self.delete_on_ms))
                } else {
                    format!("Your {t} is stopped; every disk and all your data are kept. Renew and it starts again.")
                },
            ),
            phase::TERMINATING => ("terminating", format!("Your {t} is being terminated, as you asked: its machines, disks and records are being given back.")),
            phase::TERMINATED => ("terminated", format!("Your {t} was terminated, as you asked: its machines, disks and records are gone, and nothing more is charged.")),
            phase::DELETING | phase::DELETED => ("deleted", format!("Your {t} was deleted after its paid period ended on {} and was not renewed.", iso_date(self.paid_until_ms))),
            phase::FAILED if self.captured_at_ms > 0 => ("queued", format!("Your {t} is paid and being prepared; it takes longer than usual.")),
            // ★ A32-22: the buyer reads the day we were told and the day it is set up or refunded by.
            phase::OWED => (
                "queued",
                format!(
                    "Your {t} is paid. Setting it up takes longer than usual: we were told on {} and set it up or refund you in full by {}; you get a mail either way.",
                    iso_date(self.owed_since_ms()),
                    iso_date(self.owed_since_ms().saturating_add(OWED_DEADLINE_MS))
                ),
            ),
            phase::REFUNDED => ("cancelled", format!("Your order was cancelled and {} was refunded.", self.amount.in_words())),
            phase::FAILED => ("failed", format!("Your {t} could not be set up. Nothing will be charged: the hold is being released.")),
            _ => ("failed", format!("Your {t} could not be set up, and nothing was charged: the hold is released.")),
        };
        let shown = if self.domain.is_empty() {
            self.canonical_host(&host)
        } else {
            self.domain.clone()
        };
        let url = if matches!(self.phase.as_str(), phase::CAPTURED | phase::GRACE) {
            format!("https://{shown}")
        } else {
            String::new()
        };
        (state.to_string(), words, url)
    }

    /// [`Self::operator_view`], the product called as `w` says.
    pub fn operator_view_as(
        &self,
        apex: &str,
        w: &lifecycle::ProductWords,
    ) -> (String, String, String) {
        match self.phase.as_str() {
            // F2: an operator site whose install stopped waits for its operator, its reason named.
            phase::FAILED if self.site_order && self.stuck_install() => (INSTALL_FAILED.into(), format!("{} could not be installed: {}.", w.title, self.failure_note().unwrap_or("not recorded")), String::new()),
            phase::OWED => ("owed".into(), format!("The setup failed after payment; the operator can retry or refund. Last failure: {}", self.last_failure().unwrap_or("not recorded")), String::new()),
            phase::FAILED if self.captured_at_ms > 0 => ("owed".into(), "The setup failed after payment; what was laid is being given back, then it is set up again once by itself or the operator can retry or refund.".into(), String::new()),
            // F12: a paired site names the capture step that holds it, in that step's words.
            phase::PAIRED => {
                let (st, words, url) = self.customer_view_as(apex, w);
                match capture_hold(&self.phase, &self.why) {
                    Some(held) => (st, format!("{words} Why: {held}."), url),
                    None => (st, words, url),
                }
            }
            _ => self.customer_view_as(apex, w),
        }
    }

    /// **The run's own reason and since when** (test3-holger-rs 2026-10-22: "queued (held)" with
    /// its `queue_admits` reason in `why`, shown nowhere): `(why, "YYYY-MM-DD HH:MMZ")`, since =
    /// when the run entered its phase. `None` when it says none.
    pub fn why_said(&self) -> Option<(String, String)> {
        let why = self.why.trim();
        if why.is_empty() {
            return None;
        }
        let since = self
            .history
            .iter()
            .rev()
            .find(|t| t.phase == self.phase)
            .map(|t| format!("{} {}", iso_date(t.at_ms), install_why::hm_utc(t.at_ms)))
            .unwrap_or_default();
        Some((why.to_string(), since))
    }

    /// **The newest `failed` step's own words** in the history (never the run's later `why`).
    pub fn failure_note(&self) -> Option<&str> {
        self.history
            .iter()
            .rev()
            .find(|t| t.phase == phase::FAILED && !t.note.trim().is_empty())
            .map(|t| t.note.trim())
    }

    /// **An install that was stopped** (F2): FAILED by the install deadline or abandoned by the
    /// operator — not a lay or an installer that failed by itself.
    pub fn stuck_install(&self) -> bool {
        self.phase == phase::FAILED
            && self
                .failure_note()
                .is_some_and(|n| n == ABANDONED || n.starts_with(INSTALL_DEADLINE_HEAD))
    }

    /// ★ A32-22: since when the order waits in HELD (its newest move into it; its hold or capture
    /// when the history says none).
    pub fn held_since_ms(&self) -> u64 {
        self.history
            .iter()
            .rev()
            .find(|t| t.phase == phase::HELD)
            .map(|t| t.at_ms)
            .unwrap_or(self.captured_at_ms.max(self.held_at_ms))
    }

    /// ★ A32-22: since when the order is OWED (its newest move into it).
    pub fn owed_since_ms(&self) -> u64 {
        self.history
            .iter()
            .rev()
            .find(|t| t.phase == phase::OWED)
            .map(|t| t.at_ms)
            .unwrap_or(self.captured_at_ms)
    }

    /// **The last failure, in its own words** (live 2026-10-14: an owed order said "Last
    /// failure: not recorded" while its history held it): the run's `why` while it says one,
    /// else the newest `failed` step of its history.
    pub fn last_failure(&self) -> Option<&str> {
        let why = self.why.trim();
        if !why.is_empty() {
            return Some(why);
        }
        self.history
            .iter()
            .rev()
            .find(|t| t.phase == phase::FAILED && !t.note.trim().is_empty())
            .map(|t| t.note.trim())
    }

    /// The records the customer must set, the proof named `proof` (the product's).
    pub fn customer_records_as(&self, apex: &str, proof: &str) -> Vec<CustomerRecord> {
        if self.domain.is_empty() {
            Vec::new()
        } else {
            domain::required_as(proof, &self.domain, &self.company, apex, &self.proof)
        }
    }
}

// ── the DNS ─────────────────────────────────────────────────────────────────

pub use monetize_cloud::dns::DnsRecord;

/// **The estate's names**, the kit's `subzone` shape: `<company>.<apex>`,
/// `www.`, `git.` — every one an A record to the front ([`monetize_embed::sold::SoldNames`]).
/// Refused by name: any record that would be one of the SERVING estate's own
/// names.
pub fn records_for(company: &str, apex: &str, front_ipv4: &str) -> Result<Vec<DnsRecord>, String> {
    let serving: BTreeSet<String> = ["", "www.", "git.", "monetize."]
        .iter()
        .map(|p| format!("{p}{apex}"))
        .collect();
    monetize_embed::sold::SoldNames::of(company, apex)
        .names()
        .into_iter()
        .map(|name| {
            if serving.contains(&name) {
                Err(format!(
                    "the record {name} is the serving estate's own name; nothing was written"
                ))
            } else {
                Ok(DnsRecord {
                    name,
                    kind: "A".into(),
                    value: front_ipv4.into(),
                    proxied: false,
                })
            }
        })
        .collect()
}

/// **Where an estate's names are written** — `monetize_cloud::dns::DnsWriter`:
/// the account's writer is linked (Cloudflare, `monetize-cloud-impl`, through
/// [`crate::registry::Linked::dns`]); the mock has no DNS, so [`FileDns`]
/// records what would have been written.
pub use monetize_cloud::dns::DnsWriter as EstateDns;

/// No writer here: the names are listed in the run and written by nobody.
pub struct NoDns;

impl EstateDns for NoDns {
    /// It writes into no provider's zone (RA1-5): the zone guard passes it.
    fn zoneless(&self) -> bool {
        true
    }
    fn write(&self, records: &[DnsRecord]) -> Result<String, String> {
        Ok(format!(
            "no DNS writer is configured here: {} record(s) listed in the run, none written",
            records.len()
        ))
    }
    fn remove(&self, _names: &[String]) -> Result<String, String> {
        Ok("no DNS writer is configured here: nothing to remove".into())
    }
    fn listed(&self) -> Result<Vec<DnsRecord>, String> {
        Ok(Vec::new())
    }
    fn writes(&self) -> bool {
        false
    }
}

/// **The mock's DNS**: a JSON file of records. What the account's writer
/// would hold, so a test can see the names come and go.
pub struct FileDns(pub PathBuf);

impl FileDns {
    fn save(&self, rows: &[DnsRecord]) -> Result<(), String> {
        let text = serde_json::to_vec_pretty(rows).map_err(|e| e.to_string())?;
        write_atomic(&self.0, &text)
    }
}

impl EstateDns for FileDns {
    /// It writes into no provider's zone (RA1-5): the zone guard passes it.
    fn zoneless(&self) -> bool {
        true
    }
    fn write(&self, records: &[DnsRecord]) -> Result<String, String> {
        let mut rows = self.listed()?;
        rows.retain(|r| !records.iter().any(|n| n.name == r.name));
        rows.extend(records.iter().cloned());
        self.save(&rows)?;
        Ok(format!(
            "{} record(s) written to {}",
            records.len(),
            self.0.display()
        ))
    }
    fn remove(&self, names: &[String]) -> Result<String, String> {
        let mut rows = self.listed()?;
        let before = rows.len();
        rows.retain(|r| !names.contains(&r.name));
        self.save(&rows)?;
        Ok(format!(
            "{} record(s) removed from {}",
            before - rows.len(),
            self.0.display()
        ))
    }
    fn lists(&self) -> bool {
        true
    }
    fn listed(&self) -> Result<Vec<DnsRecord>, String> {
        match std::fs::read(&self.0) {
            Ok(b) if b.is_empty() => Ok(Vec::new()),
            Ok(b) => serde_json::from_slice(&b).map_err(|e| format!("{}: {e}", self.0.display())),
            Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(Vec::new()),
            Err(e) => Err(format!("{}: {e}", self.0.display())),
        }
    }
}

/// The refusal of a config that still names a twin-health command (removed, G12).
pub const TWIN_HEALTH_COMMAND_REMOVED: &str = "[estate_orders] twin_health is REMOVED (G12, 2026-10-10): the twin's lag and load are no longer read by running a command (the kit's `cargo xtask … estate twin-health`) — the estate REPORTS them on the pull channel (its boxes' Fleet.Report `twin_review`), read natively here; monetize never dials an estate. Remove the line";
/// The refusal of a config that still names an install worker (removed, no-dwarf step 8).
pub const WORKERS_REMOVED: &str = "[estate_orders.install_workers] is REMOVED (2026-10-08, \"DWARFS MUST NOT BE INVOLVED!\"): no worker pulls a sale's install any more — the shop pairs what it sells itself (`pairing = \"shop-pairing\"`). Remove the table";

/// The words a job waiting for its DNS records to answer is parked with.
pub const DNS_WAIT: &str = "the estate's DNS records do not answer yet";

/// The DNS writer every open build has: `[estate_orders] dns = "manual"`.
pub const MANUAL_DNS: &str = "manual";

/// **The FREE DNS writer** (`dns = "manual"`, the owner 2026-10-08): the shop TELLS the operator
/// the records to set by hand — in the run, in an ALERT line — and waits until the resolver
/// (`[estate_orders] resolver`, best the zone's authoritative nameserver: `dns:<ip>:53`)
/// answers each with its value; only then does the installer start. A give-back tells which
/// names to remove. DNS-only records: a proxied name answers another address and never settles.
pub struct ManualDns {
    pub resolver: Arc<dyn domain::DomainCheck>,
}

impl ManualDns {
    /// Pure: the operator's words for records to set or remove by hand.
    pub fn said(set: bool, records: &[String]) -> String {
        format!(
            "{} by hand at the zone's DNS: {}",
            if set {
                "set these records"
            } else {
                "remove these records"
            },
            records.join(" · ")
        )
    }
}

impl EstateDns for ManualDns {
    /// It writes into no provider's zone (RA1-5): the zone guard passes it.
    fn zoneless(&self) -> bool {
        true
    }
    fn write(&self, records: &[DnsRecord]) -> Result<String, String> {
        let rows: Vec<String> = records
            .iter()
            .map(|r| format!("{} {} {}", r.kind, r.name, r.value))
            .collect();
        let line = Self::said(true, &rows);
        eprintln!("monetize-server: ALERT estate-orders.dns-by-hand: {line}");
        skidbladnir::functional_status(
            "monetize-server/estate-orders",
            "dns-by-hand",
            false,
            &line,
        );
        Ok(format!("{line}; the installer waits until they answer"))
    }
    fn remove(&self, names: &[String]) -> Result<String, String> {
        let line = Self::said(false, names);
        eprintln!("monetize-server: ALERT estate-orders.dns-by-hand: {line}");
        Ok(line)
    }
    fn listed(&self) -> Result<Vec<DnsRecord>, String> {
        Ok(Vec::new())
    }
    /// Every A record answers with its value at the resolver (other kinds are the operator's).
    fn settled(&self, records: &[DnsRecord]) -> Result<bool, String> {
        for r in records.iter().filter(|r| r.kind == "A") {
            if !self.resolver.a(&r.name)?.contains(&r.value) {
                return Ok(false);
            }
        }
        Ok(true)
    }
}

/// **The installer `[estate_orders] pairing` names**, built from what this build links —
/// refused by name when it links none of that name (an open build links none).
pub fn linked_installer(
    c: &EstateOrderConfig,
    linked: &crate::registry::Linked,
    data_dir: &std::path::Path,
) -> Result<Arc<dyn Installer>, String> {
    let name = c.pairing.trim();
    let Some(f) = linked.find_installer(name) else {
        let have = linked.installer_names();
        return Err(format!(
            "[estate_orders] pairing = {name:?}: this build links no such installer ({}); the shop's own pairing is `monetize-shop-pairing` (`ShopPairing`, linked by the solo monetize box)",
            if have.is_empty() { "it links none".to_string() } else { format!("it links {}", have.join(", ")) }
        ));
    };
    (f.build)(&crate::registry::InstallerBuild {
        orders: c,
        data_dir,
    })
    .map_err(|e| format!("[estate_orders] pairing = {name:?}: {e}"))
}

/// **The writer `[estate_orders] dns` names**: `manual` (the FREE one, every build: the
/// operator sets the records by hand and the shop waits until `resolver` answers them),
/// `file:<path>` (the mock's recording file), empty (no writer), or a LINKED writer by name
/// (`cloudflare`, the commercial build) — refused by name when this build links none. A
/// linked writer gets its zone and token from the custodian (`dns.<name>`), unsealed for each
/// call; a credential that was never sealed is said at the first write, by name.
pub fn dns_writer(
    c: &EstateOrderConfig,
    linked: &crate::registry::Linked,
    custody: &Custody,
    resolver: Arc<dyn domain::DomainCheck>,
) -> Result<Arc<dyn EstateDns>, String> {
    if let Some(p) = c.dns.strip_prefix("file:") {
        return Ok(Arc::new(FileDns(PathBuf::from(p))));
    }
    if c.dns.is_empty() {
        return Ok(Arc::new(NoDns));
    }
    if c.dns.trim() == MANUAL_DNS {
        if !resolver.reads() {
            return Err(format!(
                "[estate_orders] dns = \"{MANUAL_DNS}\": the shop waits until the records set by hand answer, and [estate_orders] resolver names none (best: the zone's authoritative nameserver, `dns:<ip>:53`)"
            ));
        }
        return Ok(Arc::new(ManualDns { resolver }));
    }
    let name = c.dns.trim();
    let Some(f) = linked.find_dns(name) else {
        let have = linked.dns_names();
        return Err(format!(
            "[estate_orders] dns = {name:?}: this build links no such DNS writer ({}); `file:<path>` is the mock's, empty is none",
            if have.is_empty() { "it links none".to_string() } else { format!("it links {}", have.join(", ")) }
        ));
    };
    let custody = custody.clone();
    let key = format!("dns.{name}");
    let credential: monetize_cloud::dns::CredentialSource = Arc::new(move || {
        let bytes = custody.unseal_credential(&key)?;
        monetize_cloud::dns::DnsCredential::from_json(&bytes)
    });
    let settings = c.dns_settings.clone();
    let w = (f.build)(monetize_cloud::dns::DnsBuild {
        name,
        settings: monetize_cloud::dns::Settings(&settings),
        credential,
    })
    .map_err(|e| format!("[estate_orders] dns = {name:?}: {e}"))?;
    Ok(Arc::from(w))
}

// ── the installer ───────────────────────────────────────────────────────────

/// **`laid.json`**: what the job hands the kit — the estate as the provider
/// laid it, and the names its front must serve (`--laid`).
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct LaidOrder {
    pub company: String,
    pub apex: String,
    /// The customer's own domain, or empty.
    #[serde(default)]
    pub domain: String,
    /// Every name the front serves and makes a certificate for.
    pub names: Vec<String>,
    pub estate: LaidEstate,
    /// **The estate's spend cap** (EUR minor a month at the provider).
    #[serde(default)]
    pub spend_cap_monthly_minor: u64,
    /// **The ONE monetize's door** (G14, G16): the configured
    /// [`EstateOrderConfig::shop_door`], never made up. The estate runs no
    /// monetize (ONE monetize, owner 2026-10-10): each of its gunnar boxes PULLS
    /// its orders here (`--fleet <shop_door> --fleet-instance <company>`), and
    /// the estate's signed `SoldEstate` calls go here. It holds no cloud token
    /// and no growth cap of its own.
    #[serde(default)]
    pub shop_door: String,
    /// **The ONE monetize's public key** (64 hex): what the boxes verify every
    /// pulled order and entitlement under (`--monetize-pubkey`).
    #[serde(default)]
    pub monetize_pubkey: String,
    /// **How long the buyer's first-login link lives**, seconds
    /// ([`EstateOrderConfig::first_login_ttl_secs`]); the kit feeds it with
    /// the invite's hash.
    #[serde(default)]
    pub first_login_ttl_secs: u64,
    /// **The estate's pay page** (lane M4): where its next period is paid — the site row's
    /// renewal page (`[estate_orders.term] renew_url` on the run's site). The pairing feeds it to
    /// a product whose front serves no pay page of its own (Holger's `refusal_link`). Empty: none.
    #[serde(default)]
    pub pay_page: String,
}

/// What the `installing` step hands the installer.
#[derive(Clone, Debug)]
pub struct InstallRequest {
    /// **What the estate's product says it is** (its lifecycle's facts, lane L18; v2.0 P3): the
    /// kind, and the contract and sale proof the pairing speaks for it. Default: no product.
    pub facts: crate::facts::Facts,
    pub company: String,
    pub apex: String,
    /// The order's owner ([`EstateRun::account`]); empty when none was named.
    pub account: String,
    /// `laid.json`: [`LaidEstate`], exactly as the provider reported it.
    pub laid: PathBuf,
    /// The custody hand-off directory ([`crate::custody::handoff`]).
    pub handoff: PathBuf,
    /// The job's own directory; the verdict is `<run>/install-verdict.json`.
    pub run: PathBuf,
    /// **The one role to lay** (`main` | `twin`) when the guardian lays a box again
    /// ([`relay::relay_one`]); empty: the whole estate.
    pub role: String,
    /// **Where the installer says what it is doing** — kept with the order and
    /// published ([`setup_log`]); silent when nobody listens.
    pub narrate: setup_log::Narrate,
    /// **The relay a sold estate's main mails through** (S10 resend, P1 2026-10-11): feed
    /// entries `secret.smtp_url` / `secret.smtp_from` of the estate's PRODUCT ([`relay_feed`]);
    /// empty: none fed.
    pub relay: BTreeMap<String, String>,
    /// **An operator site laid itself** ([`site`]): what its front is fed as the enrolled site
    /// it is. `None`: a sold estate.
    pub site: Option<SiteFeed>,
    /// **The estate's off-site copy** (lane O1, [`offsite_feed`]): the store the shop was fed
    /// for it, the estate's own prefix and, once minted, its recipient — in the feed keys the
    /// product's main reads them under. The installer feeds them to the boxes the product ships
    /// a copy from (Holger's main and twin), never the front. Empty: no copy.
    pub offsite: BTreeMap<String, String>,
}

/// What an operator site's front is fed over a sold front's feed ([`InstallRequest::site`]).
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct SiteFeed {
    /// The site's own bearer at the ONE box (its console sells as this site). Never logged.
    pub bearer: String,
    /// The product its console sells (`[estates.<site>] product`).
    pub product: String,
    /// The site's own label (`gunnar-rs`): the name its boxes pull as.
    pub label: String,
    /// **The seed's public key** (one OpenSSH line; empty: none): fed as the machine principal
    /// the kit seeds the site's declared repositories as (gunnar's `installer-seed`). Its
    /// private half never leaves the operator's kit.
    pub seed_key: String,
    /// **The site's public face is on** (`[estates.<label>] public_site`, TASKS-12): fed as
    /// `console_public_site = on`.
    pub public_site: bool,
    /// **The site's CLI hole is open to the internet** (`[estates.<label>] cli_hole_public`,
    /// RA1-14): fed as `front_cli_hole = public`.
    pub cli_hole_public: bool,
    /// **The repositories of the site's estate that are public** (`[estates.<label>]
    /// public_repositories`, NIGHT-PUBREPO): fed to its main and twin as `public_repositories`.
    pub public_repositories: Vec<String>,
}

/// The host's fed secrets naming the relay a SOLD estate's main mails through, **one per
/// product** (owner 2026-10-28: Gunnar sites send as estate@gunnar.rs, Holger sites as
/// estate@holger.rs): `<secrets_dir>/secret.sold_smtp_url.<product>`, `…sold_smtp_from.<product>`
/// ([`sold_relay_names`]), kept apart from the box's own relay (`smtp_url`) so the operator
/// decides what a buyer's box may hold.
pub const SOLD_RELAY_URL: &str = "sold_smtp_url";
pub const SOLD_RELAY_FROM: &str = "sold_smtp_from";
/// MAIL-RELAY: one more root the sold relay's certificate is trusted under (PEM, optional; a
/// relay on a private CA, the bench's), fed as [`FEED_SMTP_CA`]; per product as the relay.
pub const SOLD_RELAY_CA: &str = "sold_smtp_ca";
/// The feed keys a main reads them under (gunnar-server `feed::FEED_SMTP_*`).
pub const FEED_SMTP_URL: &str = "secret.smtp_url";
pub const FEED_SMTP_FROM: &str = "secret.smtp_from";
/// The feed key of the relay's extra root (the ONE box's own `secret.smtp_ca`).
pub const FEED_SMTP_CA: &str = "secret.smtp_ca";

/// Pure: **the names of `product`'s sold relay** in the host's secrets — `(url, from, ca)`,
/// each suffixed with the product's family as the product mail is (`smtp_url.holger`; `holger-lean` → `.holger`).
pub fn sold_relay_names(product: &str) -> (String, String, String) {
    let p = lifecycle::family_of(product).to_ascii_lowercase();
    (
        format!("{SOLD_RELAY_URL}.{p}"),
        format!("{SOLD_RELAY_FROM}.{p}"),
        format!("{SOLD_RELAY_CA}.{p}"),
    )
}

/// The relay of `product`'s sold estates as the shop holds it now; a half one is said and none
/// fed.
pub fn sold_relay(state: &AppState, product: &str) -> BTreeMap<String, String> {
    relay_feed(state.estates.relay_fed.as_deref(), product).unwrap_or_else(|why| {
        eprintln!("monetize-server: REFUSED [sold-relay] {why}: the sold {product} estate is fed no relay (its resend is refused by name)");
        BTreeMap::new()
    })
}

/// **The relay of `product`'s sold estates, as the shop was fed it**: `secret.smtp_url` /
/// `secret.smtp_from` (and `secret.smtp_ca` when the relay's root is named), all or none, from
/// that product's names alone ([`sold_relay_names`]) — never another product's.
pub fn relay_feed(
    secrets: Option<&Path>,
    product: &str,
) -> Result<BTreeMap<String, String>, String> {
    let Some(dir) = secrets else {
        return Ok(BTreeMap::new());
    };
    let read = |n: &str| {
        monetize_product_wasm::secrets::read(dir, n)
            .ok()
            .and_then(|s| String::from_utf8(s.bytes().to_vec()).ok())
            .map(|v| v.trim().to_owned())
            .filter(|v| !v.is_empty())
    };
    let (url_n, from_n, ca_n) = sold_relay_names(product);
    let p = lifecycle::family_of(product);
    match (read(&url_n), read(&from_n)) {
        // RA5-42: the old unsuffixed names (before OX-RELAY2) are said by name, never dropped.
        (None, None) if read(SOLD_RELAY_URL).is_some() || read(SOLD_RELAY_FROM).is_some() => Err(format!(
            "this box holds the old unsuffixed {SOLD_RELAY_URL}/{SOLD_RELAY_FROM} and no {url_n}/{from_n}: the sold relay is per product now, feed it under {url_n} and {from_n}"
        )),
        (None, None) => Ok(BTreeMap::new()),
        (Some(url), Some(from)) => {
            let mut f = BTreeMap::from([(FEED_SMTP_URL.to_owned(), url), (FEED_SMTP_FROM.to_owned(), from)]);
            if let Some(ca) = read(&ca_n) {
                f.insert(FEED_SMTP_CA.to_owned(), ca);
            }
            Ok(f)
        }
        (Some(_), None) => Err(format!("the {p} sold estates' relay is named ({url_n}) and its sender is not ({from_n})")),
        (None, Some(_)) => Err(format!("the {p} sold estates' sender is named ({from_n}) and its relay is not ({url_n})")),
    }
}

/// **The boot's word on the old unsuffixed sold-relay names** (RA5-42): `secret.sold_smtp_url`
/// / `…sold_smtp_from` from before OX-RELAY2 are read by nobody now. `Some(ALERT …)` when this
/// box still holds one, so the operator feeds the per-product names before a buyer's mail is
/// refused.
pub fn unsuffixed_relay_alert(secrets: &Path) -> Option<String> {
    let held: Vec<&str> = [SOLD_RELAY_URL, SOLD_RELAY_FROM, SOLD_RELAY_CA]
        .into_iter()
        .filter(|n| monetize_product_wasm::secrets::read(secrets, n).is_ok())
        .collect();
    (!held.is_empty()).then(|| {
        format!(
            "ALERT sold-relay.unsuffixed this box holds {} (the names before the relay went per product): nothing reads them; feed {}.<product> and {}.<product> for each product it sells",
            held.iter().map(|n| format!("secret.{n}")).collect::<Vec<_>>().join(", "),
            SOLD_RELAY_URL,
            SOLD_RELAY_FROM
        )
    })
}

/// The host's fed secrets naming the store an operator site's estate ships its OFF-SITE copy
/// to (lane O1, `<secrets_dir>/secret.sold_offsite_*`): the operator's store, kept apart from
/// the box's own off-box copy's feed, as the sold relay is from the box's relay. All four or
/// none.
pub const SOLD_OFFSITE_ENDPOINT: &str = "sold_offsite_r2_endpoint";
pub const SOLD_OFFSITE_BUCKET: &str = "sold_offsite_bucket";
pub const SOLD_OFFSITE_ACCESS_KEY: &str = "sold_offsite_r2_access_key";
pub const SOLD_OFFSITE_SECRET_KEY: &str = "sold_offsite_r2_secret_key";
/// **The feed keys an estate's main reads its off-site copy from** (holger server-lib
/// `offsite::FEED_*`, lane M5) — the same words the ONE box's own copy is fed in.
pub const FEED_OFFSITE_RECIPIENT: &str = "offsite_recipient";
pub const FEED_OFFSITE_ENDPOINT: &str = "offsite_r2_endpoint";
pub const FEED_OFFSITE_BUCKET: &str = "offsite_bucket";
pub const FEED_OFFSITE_PREFIX: &str = "offsite_prefix";
pub const FEED_OFFSITE_ACCESS_KEY: &str = "secret.offsite_r2_access_key";
pub const FEED_OFFSITE_SECRET_KEY: &str = "secret.offsite_r2_secret_key";

/// **The estate's off-site prefix**: `<product>/<company>/` — one estate's copies under its own
/// name, every product's under its own.
pub fn offsite_prefix(product: &str, company: &str) -> String {
    let p = product.trim();
    format!(
        "{}/{}/",
        if p.is_empty() { "estate" } else { p },
        company.trim()
    )
}

/// **The estate's off-site feed, as the shop was fed its store** (lane O1): `Ok(empty)` when the
/// host was fed no store; the four store keys, the estate's prefix and (when one was minted)
/// its recipient otherwise; half a store is refused by the NAMES it lacks, never a value.
pub fn offsite_feed(
    secrets: Option<&Path>,
    product: &str,
    company: &str,
    recipient: Option<&str>,
) -> Result<BTreeMap<String, String>, String> {
    let Some(dir) = secrets else {
        return Ok(BTreeMap::new());
    };
    let read = |n: &str| {
        monetize_product_wasm::secrets::read(dir, n)
            .ok()
            .and_then(|s| String::from_utf8(s.bytes().to_vec()).ok())
            .map(|v| v.trim().to_owned())
            .filter(|v| !v.is_empty())
    };
    let names = [
        (SOLD_OFFSITE_ENDPOINT, FEED_OFFSITE_ENDPOINT),
        (SOLD_OFFSITE_BUCKET, FEED_OFFSITE_BUCKET),
        (SOLD_OFFSITE_ACCESS_KEY, FEED_OFFSITE_ACCESS_KEY),
        (SOLD_OFFSITE_SECRET_KEY, FEED_OFFSITE_SECRET_KEY),
    ];
    let got: Vec<(&str, &str, Option<String>)> = names
        .iter()
        .map(|(host, feed)| (*host, *feed, read(host)))
        .collect();
    if got.iter().all(|(_, _, v)| v.is_none()) {
        return Ok(BTreeMap::new());
    }
    let missing: Vec<&str> = got
        .iter()
        .filter(|(_, _, v)| v.is_none())
        .map(|(h, _, _)| *h)
        .collect();
    if !missing.is_empty() {
        return Err(format!(
            "the off-site store is fed without {}",
            missing.join(", ")
        ));
    }
    let mut f: BTreeMap<String, String> = got
        .into_iter()
        .filter_map(|(_, feed, v)| v.map(|v| (feed.to_string(), v)))
        .collect();
    f.insert(
        FEED_OFFSITE_PREFIX.to_string(),
        offsite_prefix(product, company),
    );
    if let Some(r) = recipient.map(str::trim).filter(|r| !r.is_empty()) {
        f.insert(FEED_OFFSITE_RECIPIENT.to_string(), r.to_string());
    }
    Ok(f)
}

/// **What an estate's install is fed of its off-site copy** (lane O1): the site's OWN estate,
/// on a site that says `offsite` ([`crate::registry::Linked::offsite`]), the store the shop holds
/// now and the recipient its custody keeps; nothing for any other estate. A half store is
/// said and none fed.
pub fn site_offsite(state: &AppState, run: &EstateRun, product: &str) -> BTreeMap<String, String> {
    if !run.site_order || !state.registry.offsite(&run.estate) {
        return BTreeMap::new();
    }
    let recipient = state
        .estates
        .custody
        .as_ref()
        .and_then(|c| c.offsite_recipient(&run.company).ok().flatten());
    offsite_feed(
        state.estates.relay_fed.as_deref(),
        product,
        &run.company,
        recipient.as_deref(),
    )
    .unwrap_or_else(|why| {
        eprintln!(
            "monetize-server: REFUSED [site-offsite] {why}: {} is fed no off-site copy",
            run.reference
        );
        BTreeMap::new()
    })
}

/// **The installer's verdict file** (`install-verdict.json`), written by the
/// kit beside `laid.json` whatever the outcome.
#[derive(Clone, Debug, PartialEq, serde::Serialize, serde::Deserialize)]
pub struct InstallVerdict {
    /// `PASS` | `FAIL`.
    pub verdict: String,
    #[serde(default)]
    pub detail: String,
    /// The kit's own receipt (commits, medium digest, the log gate's verdict).
    #[serde(default)]
    pub receipt: serde_json::Value,
    /// **The estate's WireGuard peer map**, from the installer's door: every
    /// box's tunnel PUBLIC key (made on the box), overlay and utility address.
    #[serde(default)]
    pub peers: Vec<WgPeer>,
    /// **Each box's fleet key** (base64 Ed25519 public key, by role) as the box made it, when
    /// the kit read it back; a role it names none for pins its own key on its first call to
    /// the pull channel inside the pin window (G-D5).
    #[serde(default)]
    pub appliance_keys: BTreeMap<String, String>,
    /// **The ticket key the estate's primary offered** (64 hex, its `ticket_pubkey`), when the
    /// installer read it: an operator site's accounts' tickets are checked under it ([`site`]).
    #[serde(default)]
    pub ticket_key: String,
}

/// One box of an estate's WireGuard mesh, as monetize keeps it: public halves only.
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(default)]
pub struct WgPeer {
    pub name: String,
    pub kind: String,
    pub overlay: String,
    pub utility: String,
    pub endpoint: String,
    pub public_key: String,
}

pub const VERDICT_FILE: &str = "install-verdict.json";

/// The custody files of the order's seeds: `seed.<kind>.toml` (`front`, and the sold
/// product's box kind: `gunnar`, `holger`).
pub const SEED_FILE_PREFIX: &str = "seed.";

/// The medium kinds a paired lay of `c`'s product needs: its lifecycle's front and app media.
/// A product whose lifecycle is not known yet (its guest not followed) names none here; its
/// order is refused by name at the start, before any money moves, when one is missing.
fn media_kinds_of(c: &EstateOrderConfig) -> Vec<String> {
    match lifecycle::of(c) {
        Ok(l) => {
            let u = l.update_plan();
            let mut v = vec![u.front_medium, u.app_medium];
            v.retain(|k| !k.is_empty());
            v.dedup();
            v
        }
        Err(_) => Vec::new(),
    }
}

/// Pure: **why `[estate_orders.media]` cannot lay a paired estate**, or `None` — a kind with
/// no release medium, or one that names no storage.
pub fn media_missing(c: &EstateOrderConfig) -> Option<String> {
    let kinds = media_kinds_of(c);
    let missing: Vec<&str> = kinds
        .iter()
        .map(String::as_str)
        .filter(|k| {
            c.media.get(*k).is_none_or(|u| u.trim().is_empty())
                && c.media_objects
                    .get(*k)
                    .is_none_or(|o| o.url.trim().is_empty() || o.sha256.len() != 64)
        })
        .collect();
    (!missing.is_empty()).then(|| {
        format!(
            "[estate_orders] pairs the estate itself (`pairing = {:?}`) and neither [estate_orders.media] nor [estate_orders.media_objects] names a release medium for {}: a sold estate's machines are cloned from the release's seedless media (`cargo xtask estate release-image` uploads them once per release)",
            c.pairing.trim(),
            missing.join(" and ")
        )
    })
}

/// **Does every site name its media where the shop names none?** (2026-10-11: test2 sells
/// from DEV media, gunnar.rs from the release.) The shop's own complete media answer for
/// every site; else each declared site of the sold product must name its own
/// (`[estates.<e>.orders] media`/`media_objects`). Stub until GREEN.
pub fn media_missing_on_sites(
    c: &EstateOrderConfig,
    estates: &BTreeMap<String, crate::config::EstateConfig>,
) -> Option<String> {
    let own = media_missing(c)?;
    let product = c.product.trim();
    let sites: Vec<(&String, &crate::config::EstateConfig)> = estates
        .iter()
        .filter(|(_, e)| e.product == product)
        .collect();
    // ★ T2-BOX (owner 2026-11-03: an EMPTY box): no site of the product yet lays nothing — every
    // order is bought on a site. The site the operator adds later names its own media, and the
    // box's loader judges it then (a site with none is refused below, by name).
    if sites.is_empty() {
        return None;
    }
    let lacking: Vec<String> = sites
        .iter()
        .filter_map(|(id, e)| {
            let site = EstateOrderConfig {
                media: e.orders.media.clone(),
                media_objects: e.orders.media_objects.clone(),
                pairing: c.pairing.clone(),
                product: c.product.clone(),
                lifecycle: c.lifecycle.clone(),
                ..EstateOrderConfig::default()
            };
            media_missing(&site).map(|_| id.to_string())
        })
        .collect();
    (!lacking.is_empty()).then(|| format!("{own} — and the site(s) {} name no media of their own ([estates.<e>.orders] media / media_objects)", lacking.join(", ")))
}

/// Pure: **the sites that write their own zone, and with which writer** — every declared site
/// naming `[estates.<e>.orders] dns`, of ANY product the box lays (lane L13, 2026-10-18: a
/// Holger site on the box that sells Gunnar writes holger.rs with its own writer, never the
/// shop's gunnar.rs one).
pub fn site_dns_writers(
    estates: &BTreeMap<String, crate::config::EstateConfig>,
) -> BTreeMap<String, String> {
    estates
        .iter()
        .filter_map(|(id, e)| {
            e.orders
                .dns
                .as_deref()
                .map(str::trim)
                .filter(|w| !w.is_empty())
                .map(|w| (id.clone(), w.to_owned()))
        })
        .collect()
}

/// **The writer `c.dns` names, or a refusal that says why by name** (2026-10-11): a writer this
/// build does not link no longer stops the shop (the ONE box, linking none, fed `dns =
/// "cloudflare"`): it SELLS nothing for that zone and says so. Stub until GREEN.
pub fn writer_or_refused(
    c: &EstateOrderConfig,
    linked: &crate::registry::Linked,
    custody: &Custody,
    resolver: Arc<dyn domain::DomainCheck>,
    guests: &BTreeMap<String, serde_json::Value>,
    data_dir: &Path,
) -> Arc<dyn EstateDns> {
    // A writer declared as a signed guest (`[dns_writers.<name>]`, the owner 2026-10-11): the
    // provider is a plugin the server takes in, never linked.
    let built = match guests.get(c.dns.trim()) {
        // Held live (2026-10-17): a module written over this one is taken in by the watcher.
        Some(block) => monetize_cloud_wasm::dns::HotDns::build(data_dir, c.dns.trim(), block)
            .map(|g| g as Arc<dyn EstateDns>),
        None => dns_writer(c, linked, custody, resolver),
    };
    // Every writer is held behind its zone (A32-3): a name outside it is refused by name here,
    // before the writer (a guest, a linked provider) is asked; the guest's own refusal is the
    // second line.
    built
        .map(|w| Arc::new(monetize_cloud::dns::Zoned(w)) as Arc<dyn EstateDns>)
        .unwrap_or_else(|why| {
            eprintln!("{}", writer_refused_line(&why));
            Arc::new(RefusedDns(why))
        })
}

/// **The operator's line for a refused writer**: the writer and the refusal's clause ids,
/// [`log_safe`] — the box's log redactor (nordisk-pairing `redact`) withholds a WHOLE line
/// that says "secret" or "token", and on 2026-10-12 it withheld exactly this refusal
/// (`[secret-dir] …`): the operator read only "this shop writes no DNS records".
pub fn writer_refused_line(why: &str) -> String {
    format!("monetize-server: estate orders: ALERT estate-orders.dns-writer {} — nothing is sold where it writes", log_safe(why))
}

/// The words the box's log redactor withholds a whole line for (nordisk-pairing
/// `redact::class`, the `token` class), lower case.
pub const REDACTOR_WORDS: &[&str] = &["secret", "token", "bearer", "password"];

/// **A sentence the box's log redactor keeps** — each of [`REDACTOR_WORDS`], in any case, is
/// spelt with its second letter starred (`[secret-dir]` → `[s*cret-dir]`, `Bearer` →
/// `B*arer`). For OUR OWN sentences (a refusal's words and clause ids) only: a value is
/// never put in one, so nothing is unredacted by it; the redactor still withholds every
/// line that carries a credential's shape.
pub fn log_safe(s: &str) -> String {
    let lower = s.to_ascii_lowercase();
    let mut out: Vec<u8> = s.as_bytes().to_vec();
    for w in REDACTOR_WORDS {
        let mut from = 0;
        while let Some(i) = lower[from..].find(w) {
            out[from + i + 1] = b'*';
            from += i + w.len();
        }
    }
    String::from_utf8(out).unwrap_or_else(|_| s.to_string())
}

/// **The `[dns_writers.<name>]` blocks as the server loads them**: every block that names a
/// guest is given the deployment's secrets directory (`Config::secrets_dir`, where the feed
/// writes `secret.<name>`), exactly as a `[clouds.<name>]` guest is (`registry`, the cloud
/// factory) — a top-level key, so the block cannot name it. Without it the loader refused a
/// writer whose `http_auth` names its token ([secret-dir], the ONE box 2026-10-12), and a
/// writer that loaded would have read `<data_dir>/secrets`, where nothing is fed.
pub fn dns_guest_blocks(
    guests: &BTreeMap<String, serde_json::Value>,
    secrets_dir: &Path,
) -> BTreeMap<String, serde_json::Value> {
    guests
        .iter()
        .map(|(name, block)| {
            let mut b = block.clone();
            if b.get("guest").is_some() {
                if let Some(obj) = b.as_object_mut() {
                    obj.insert(
                        "secrets_dir".into(),
                        serde_json::Value::String(secrets_dir.display().to_string()),
                    );
                }
            }
            (name.clone(), b)
        })
        .collect()
}

/// **A DNS writer that could not be built**: it writes nothing and says why, by name.
pub struct RefusedDns(pub String);

impl EstateDns for RefusedDns {
    /// It writes into no provider's zone (RA1-5): the zone guard passes it.
    fn zoneless(&self) -> bool {
        true
    }
    fn write(&self, _records: &[DnsRecord]) -> Result<String, String> {
        Err(self.0.clone())
    }
    fn remove(&self, _names: &[String]) -> Result<String, String> {
        Err(self.0.clone())
    }
    fn listed(&self) -> Result<Vec<DnsRecord>, String> {
        Ok(Vec::new())
    }
    fn writes(&self) -> bool {
        false
    }
}

/// Pure: **each machine's release medium**: the storage of its role's kind (`life`'s
/// [`lifecycle::Lifecycle::medium_kind`], `[estate_orders.media]`), cloned at the lay; a
/// kind with no storage laid from its OBJECT (`[estate_orders.media_objects]`, its url already
/// presigned for this lay when the shop holds the bucket's read key — [`presigned_objects`]); a
/// kind with neither is left to the provider's own template.
pub fn give_release_media_as(
    plan: &mut monetize_cloud::lay::EstatePlan,
    media: &BTreeMap<String, String>,
    objects: &BTreeMap<String, monetize_cloud::lay::MediaObject>,
    life: &lifecycle::Lifecycle,
) {
    give_release_media_by(plan, media, objects, &|role| life.medium_kind(role))
}

fn give_release_media_by(
    plan: &mut monetize_cloud::lay::EstatePlan,
    media: &BTreeMap<String, String>,
    objects: &BTreeMap<String, monetize_cloud::lay::MediaObject>,
    kind_of: &dyn Fn(&str) -> String,
) {
    for m in plan.machines.iter_mut() {
        let kind = kind_of(&m.role);
        let kind = kind.as_str();
        if let Some(uuid) = media.get(kind).map(|u| u.trim()).filter(|u| !u.is_empty()) {
            m.medium = uuid.to_string();
        } else if let Some(o) = objects.get(kind).filter(|o| !o.url.trim().is_empty()) {
            m.medium_object = Some(o.clone());
        }
    }
}

/// **A release template** (`[estate_orders.templates.<kind>]`): the provider's template id,
/// and the release ([`release_id`]) whose medium it was installed from.
#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ReleaseTemplate {
    pub uuid: String,
    pub for_release: String,
    /// The template's storage tier, which a disk cloned from it is laid in. Unset:
    /// [`TEMPLATE_TIER`] (UpCloud templatizes only `maxiops`).
    #[serde(default, skip_serializing_if = "String::is_empty")]
    pub tier: String,
}

/// The tier of a template that names none: UpCloud makes templates only of `maxiops`
/// storage ("Only maxiops storages can be templatized").
pub const TEMPLATE_TIER: &str = "maxiops";

impl ReleaseTemplate {
    /// The tier a disk cloned from this template is laid in.
    pub fn tier(&self) -> &str {
        if self.tier.trim().is_empty() {
            TEMPLATE_TIER
        } else {
            self.tier.trim()
        }
    }
}

/// Pure: **the template `kind`'s machines are laid from**, when there is one made for the
/// release sold now — the one rule [`give_templates_as`] and [`plan_for_as`]'s disk tiers share.
pub fn template_of<'a>(c: &'a EstateOrderConfig, kind: &str) -> Option<&'a ReleaseTemplate> {
    let t = c
        .templates
        .get(kind)
        .filter(|t| !t.uuid.trim().is_empty())?;
    let sold = release_id(c, kind);
    (!sold.is_empty() && t.for_release == sold).then_some(t)
}

/// Pure: **each machine laid from its kind's template** — only a template made for the release
/// sold now (`release_id(c, kind)`); the medium stays named (a template that is gone at the
/// provider is the lay's refusal, never a silent install). Returns, per role, what was given
/// or why not (said in the order's log). Each role's medium kind as `life` says.
pub fn give_templates_as(
    plan: &mut monetize_cloud::lay::EstatePlan,
    c: &EstateOrderConfig,
    life: &lifecycle::Lifecycle,
) -> Vec<String> {
    let mut said = Vec::new();
    for m in plan.machines.iter_mut() {
        let kind = life.medium_kind(&m.role);
        let kind = kind.as_str();
        let Some(t) = c.templates.get(kind).filter(|t| !t.uuid.trim().is_empty()) else {
            continue;
        };
        let sold = release_id(c, kind);
        if sold.is_empty() || t.for_release != sold {
            said.push(format!("{}: the {kind} template {} was made for another release ({}) than the one sold now ({}): laid from the medium", m.role, t.uuid, t.for_release, if sold.is_empty() { "none" } else { &sold }));
            continue;
        }
        m.template = t.uuid.trim().to_string();
        said.push(format!(
            "{}: laid from the {kind} template {} (release {})",
            m.role,
            m.template,
            &sold[..sold.len().min(12)]
        ));
    }
    said
}

/// **The release's identity** for a medium kind: its storage id (`[estate_orders.media]`) or
/// its object's sha256 (`[estate_orders.media_objects]`); empty when none is named. A box laid
/// or upgraded from the release's media runs `release_id(cfg, "gunnar")`.
pub fn release_id(c: &EstateOrderConfig, kind: &str) -> String {
    match c
        .media
        .get(kind)
        .map(|u| u.trim())
        .filter(|u| !u.is_empty())
    {
        Some(id) => id.to_string(),
        None => c
            .media_objects
            .get(kind)
            .map(|o| o.sha256.clone())
            .unwrap_or_default(),
    }
}

/// **The bucket's READ key** the shop presigns release media with: `media.objsto` in the
/// custody, `{"access_key_id": …, "secret_access_key": …, "region": …}`. Never printed.
#[derive(serde::Deserialize)]
pub struct ObjstoKey {
    pub access_key_id: String,
    pub secret_access_key: String,
    #[serde(default = "default_objsto_region")]
    pub region: String,
}

fn default_objsto_region() -> String {
    "auto".into()
}

/// The custody credential the bucket's READ pair is sealed as.
pub const MEDIA_OBJSTO: &str = "media.objsto";
/// The fed secret (`<secrets_dir>/secret.media_objsto`) it arrives as from the kit.
pub const MEDIA_OBJSTO_FED: &str = "secret.media_objsto";

/// How long a presigned release-medium URL lives: the provider's import starts within it.
pub const MEDIA_PRESIGN_SECS: u64 = 3_600;

/// **The release objects for this lay**: each url presigned for [`MEDIA_PRESIGN_SECS`] when
/// the custody holds `media.objsto`, else as configured (a public object).
#[allow(unused_variables)]
pub fn presigned_objects(
    c: &EstateOrderConfig,
    custody: Option<&Custody>,
    fed: Option<&Path>,
    now_secs: u64,
) -> Result<BTreeMap<String, monetize_cloud::lay::MediaObject>, String> {
    let key: Option<ObjstoKey> = match custody.map(|c| c.unseal_credential(MEDIA_OBJSTO)) {
        Some(Ok(bytes)) => Some(serde_json::from_slice(&bytes).map_err(|e| format!("the custody's {MEDIA_OBJSTO} is not {{access_key_id, secret_access_key, region}}: {e}"))?),
        // **Fed, not yet sealed** (F-O2): the kit feeds a selling front the bucket's READ pair as
        // `secret.media_objsto`; the first lay seals it into the custody, where it stays.
        _ => match (custody, fed.and_then(|f| std::fs::read(f).ok()).filter(|b| !b.is_empty())) {
            (Some(cu), Some(bytes)) => {
                let k: ObjstoKey = serde_json::from_slice(&bytes).map_err(|e| format!("the fed {MEDIA_OBJSTO} is not {{access_key_id, secret_access_key, region}}: {e}"))?;
                cu.seal_credential(MEDIA_OBJSTO, &bytes).map_err(|e| format!("sealing {MEDIA_OBJSTO}: {e}"))?;
                Some(k)
            }
            _ => None,
        },
    };
    c.media_objects
        .iter()
        .map(|(kind, o)| {
            let url = match &key {
                #[cfg(any(test, feature = "custody-ring"))]
                Some(k) => presign_get(&o.url, k, now_secs, MEDIA_PRESIGN_SECS)?,
                #[cfg(not(any(test, feature = "custody-ring")))]
                Some(_) => {
                    return Err("this build cannot presign (custody-ring is off)".to_string())
                }
                None => o.url.clone(),
            };
            Ok((
                kind.clone(),
                monetize_cloud::lay::MediaObject { url, ..o.clone() },
            ))
        })
        .collect()
}

#[cfg(any(test, feature = "custody-ring"))]
/// Pure: **an S3 GET presigned with AWS SigV4** (query auth, `UNSIGNED-PAYLOAD`) for a
/// path-style object `url` (`https://<endpoint>/<bucket>/<key>`), valid `expires` seconds from
/// `now_secs`.
pub fn presign_get(
    url: &str,
    k: &ObjstoKey,
    now_secs: u64,
    expires: u64,
) -> Result<String, String> {
    use ring::{digest, hmac};
    let (scheme, rest) = url
        .split_once("://")
        .ok_or_else(|| format!("{}: not a URL", url.split('?').next().unwrap_or("")))?;
    let (host, path) = rest
        .split_once('/')
        .map(|(h, p)| (h, format!("/{p}")))
        .unwrap_or((rest, "/".into()));
    let path = path.split('?').next().unwrap_or("/").to_string();
    let amz_date = amz_date_of(now_secs);
    let date = &amz_date[..8];
    let scope = format!("{date}/{}/s3/aws4_request", k.region);
    let enc = |s: &str| {
        s.bytes()
            .map(|b| {
                if b.is_ascii_alphanumeric() || b"-_.~".contains(&b) {
                    (b as char).to_string()
                } else {
                    format!("%{b:02X}")
                }
            })
            .collect::<String>()
    };
    let canonical_path = path.split('/').map(enc).collect::<Vec<_>>().join("/");
    let credential = format!("{}/{scope}", k.access_key_id);
    let query = format!(
        "X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential={}&X-Amz-Date={amz_date}&X-Amz-Expires={expires}&X-Amz-SignedHeaders=host",
        enc(&credential)
    );
    let canonical =
        format!("GET\n{canonical_path}\n{query}\nhost:{host}\n\nhost\nUNSIGNED-PAYLOAD");
    let hex = |b: &[u8]| b.iter().map(|x| format!("{x:02x}")).collect::<String>();
    let to_sign = format!(
        "AWS4-HMAC-SHA256\n{amz_date}\n{scope}\n{}",
        hex(digest::digest(&digest::SHA256, canonical.as_bytes()).as_ref())
    );
    let mac = |key: &[u8], m: &str| {
        hmac::sign(&hmac::Key::new(hmac::HMAC_SHA256, key), m.as_bytes())
            .as_ref()
            .to_vec()
    };
    let kd = mac(
        &mac(
            &mac(
                &mac(format!("AWS4{}", k.secret_access_key).as_bytes(), date),
                &k.region,
            ),
            "s3",
        ),
        "aws4_request",
    );
    let sig = hex(&mac(&kd, &to_sign));
    Ok(format!(
        "{scheme}://{host}{canonical_path}?{query}&X-Amz-Signature={sig}"
    ))
}

/// `YYYYMMDDTHHMMSSZ` of a Unix time, UTC (pure).
pub fn amz_date_of(secs: u64) -> String {
    let days = (secs / 86_400) as i64;
    let rem = secs % 86_400;
    // Civil from days (Howard Hinnant).
    let z = days + 719_468;
    let era = z.div_euclid(146_097);
    let doe = z - era * 146_097;
    let yoe = (doe - doe / 1_460 + doe / 36_524 - doe / 146_096) / 365;
    let doy = doe - (365 * yoe + yoe / 4 - yoe / 100);
    let mp = (5 * doy + 2) / 153;
    let d = doy - (153 * mp + 2) / 5 + 1;
    let m = if mp < 10 { mp + 3 } else { mp - 9 };
    let y = yoe + era * 400 + i64::from(m <= 2);
    format!(
        "{y:04}{m:02}{d:02}T{:02}{:02}{:02}Z",
        rem / 3_600,
        rem % 3_600 / 60,
        rem % 60
    )
}

/// Pure: **each machine's user_data from the sealed seeds** — `seed.<kind>.toml` by its
/// role's kind as `life` says; a machine whose kind has no seed gets none.
pub fn give_seeds_as(
    plan: &mut monetize_cloud::lay::EstatePlan,
    material: &[(String, String)],
    life: &lifecycle::Lifecycle,
) {
    give_seeds_by(plan, material, &|role| life.medium_kind(role))
}

fn give_seeds_by(
    plan: &mut monetize_cloud::lay::EstatePlan,
    material: &[(String, String)],
    kind_of: &dyn Fn(&str) -> String,
) {
    for m in plan.machines.iter_mut() {
        let want = format!("{SEED_FILE_PREFIX}{}.toml", kind_of(&m.role));
        if let Some((_, text)) = material.iter().find(|(n, _)| *n == want) {
            m.user_data = monetize_cloud::lay::UserData(text.clone());
        }
    }
}

/// **The `installing` step's seam**: monetize invokes the kit; it does not link
/// it (PRIVATE-GUNNAR.md §2).
/// **A site's first-admin door, as its public front answers** (owner 2026-10-22): asked before
/// the operator sends a site's first sign-in link again ([`first_link`]).
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum FirstDoor {
    /// Unspent, and the custody's invite opens it: the link can be sent again.
    Open,
    /// The first admin has signed in: the door is spent.
    Spent,
    /// Unspent, but the custody's invite no longer opens it (its lifetime is over): why.
    Closed(String),
}

pub trait Installer: Send + Sync {
    /// Install gunnar on the laid servers. `Ok` is the verdict the installer
    /// wrote — a `FAIL` included; `Err` is an installer that could not run or
    /// wrote nothing.
    fn install(&self, req: &InstallRequest) -> Result<InstallVerdict, String>;
    /// **The order's pairing material, minted BEFORE the lay** (the shop pairs the estate
    /// itself, 2026-10-08): the files the custody seals beside the order's seeds — the
    /// installer CA and its keys, the link keys, and each machine KIND's seed
    /// (`seed.front.toml`, `seed.gunnar.toml`, [`SEED_FILE_PREFIX`]) that the lay hands that
    /// machine as its `user_data`. Empty (the default): the installer brings its own media.
    /// **The sale check, over the PUBLIC front** (S4, stinky 2026-10-10): before the order is
    /// captured — its term started and the buyer mailed the first-login link — the installer
    /// proves the sold instance serves what the buyer is about to be sent to, at
    /// `https://<host>` (the name the customer reaches; never the estate's WireGuard or
    /// utility net): (1) the login page answers, (2) the first-login door answers the invite
    /// the ready mail will carry, (3) exactly ONE `<account>/welcome` repository exists. `Ok`
    /// is the words of what was proven. `Err` keeps the order at `paired`, nothing captured,
    /// until its deadline gives it back like any estate that never answered. The default:
    /// this installer proves nothing, so nothing it installs is captured.
    fn sale_check(&self, at: &SaleCheckAt<'_>) -> Result<String, String> {
        let _ = at;
        Err(
            "this shop's installer proves no sale check (S4): the public front was not looked at"
                .into(),
        )
    }
    /// [`Installer::mint`] for an estate of the product `facts` describe (lane L18: a site of
    /// another product on a box that sells one is minted its own product's material).
    /// Default: [`Installer::mint`].
    fn mint_for(
        &self,
        facts: &crate::facts::Facts,
        company: &str,
        host: &str,
    ) -> Result<Vec<(String, String)>, String> {
        let _ = facts;
        self.mint(company, host)
    }
    fn mint(&self, company: &str, host: &str) -> Result<Vec<(String, String)>, String> {
        let _ = (company, host);
        Ok(Vec::new())
    }
    /// **Is there an install path at all?** (the Sells rule, 2026-10-08): `false` only for the
    /// shop that names none — it SELLS nothing (`EstateOrder.Sells` false, `Start` refused
    /// before any money moves).
    fn installs(&self) -> bool {
        true
    }
    /// **The site's first-admin door at its public front** (owner 2026-10-22), as the sale
    /// check finds it: spent, open to the custody's invite, or closed to it. The default: this
    /// installer cannot ask.
    fn first_door(&self, at: &SaleCheckAt<'_>) -> Result<FirstDoor, String> {
        let _ = at;
        Err("this shop's installer cannot ask a site's first-admin door".into())
    }
    /// **Every laid box's pair status, asked again over the installer link** (F5, 2026-10-20:
    /// test3-holger-rs was FAILED by its install deadline, then a reboot of its front paired
    /// every box, and the ONE box still read it as failed). Only asked, never changed: no box
    /// is fed, closed or re-laid. `req` is the order's install request (its laid file, the
    /// hand-off with the installer's material, its run directory). The default: this installer
    /// cannot ask, so the operator's retry lays the estate fresh.
    fn pair_status(&self, _req: &InstallRequest) -> Result<PairCheck, String> {
        Err("this installer cannot ask the boxes their pair status again".into())
    }
    /// ★ **The fleet seam fed again to a PAIRED estate that has not called home** (HRS-DIAG
    /// 2026-11-03: holger.rs paired while this box's sale feed named no `fleet_at`, so its main
    /// and twin, laid with no public IPv4 and no DNS, could never report). Over each box's
    /// installer link, with the custody's material (`req.handoff`): every box re-fed what it was
    /// fed with the seam this box's sale feed names NOW added, nothing else changed, nothing
    /// laid. `Ok(None)`: nothing to feed (its boxes already hold that seam); `Ok(Some(words))`:
    /// fed again. `instance` is the estate the ONE box knows the boxes by (the run's fleet name:
    /// an operator site's label, else its company), never another. The default: this installer
    /// feeds nothing again.
    fn refeed_seam(
        &self,
        _req: &InstallRequest,
        _instance: &str,
    ) -> Result<Option<String>, String> {
        Ok(None)
    }
    /// **`GET /live/running` on `role`'s log door, over the installer link, with the custody's
    /// installer material** (F9, 2026-10-21: test3-holger-rs's front never took its material, so
    /// its primary keeps none and the front cannot reach its twin's live door; the ONE box takes
    /// that box's update step from the custody's copy, [`update::custody_step`]). `req` is the
    /// order's install request as for [`Installer::pair_status`]. The default: this installer
    /// reaches no live door (`[live-unsupported]`: the box is then upgraded from its keep medium).
    fn live_running(
        &self,
        _req: &InstallRequest,
        role: &str,
    ) -> Result<update::LiveRunning, String> {
        Err(format!(
            "[live-unsupported] this installer reaches no live door: the {role}'s is not asked"
        ))
    }
    /// **`POST /live/stage` to `role`'s log door** over the installer link, with the custody's
    /// installer material (F9). The default: refused.
    fn live_stage(
        &self,
        _req: &InstallRequest,
        role: &str,
        _stage: &update::LiveStage,
    ) -> Result<String, String> {
        Err(format!(
            "[live-unsupported] this installer stages nothing: the {role} is not staged"
        ))
    }
}

/// **What a re-check heard** ([`Installer::pair_status`]): each laid box by its role, its pair
/// status line as the box said it (`   pair   twin: … · PAIRED`), or why it did not answer; and
/// the ticket key the primary offers (empty: none).
#[derive(Clone, Debug, Default, PartialEq, Eq)]
pub struct PairCheck {
    pub boxes: Vec<(String, Result<String, String>)>,
    pub ticket_key: String,
}

/// No installer configured: refused by name.
pub struct NoInstaller;

impl Installer for NoInstaller {
    fn install(&self, _req: &InstallRequest) -> Result<InstallVerdict, String> {
        Err("[estate_orders] installer is empty: nothing here can install an estate".into())
    }
    fn installs(&self) -> bool {
        false
    }
}

/// **The DNS writer's credential, as the kit FEEDS it** (S2): `<secrets_dir>/secret.dns_<name>`,
/// `{"zone_id": …, "api_token": …}`; sealed into the custody as `dns.<name>` (replacing an older
/// one) and the fed file removed. `Ok(false)`: nothing fed (a `file:`/`manual`/empty writer has
/// no credential). A fed file that is not a credential is refused by name, never its value.
pub fn seal_fed_dns(custody: &Custody, secrets_dir: &Path, name: &str) -> Result<bool, String> {
    if name.is_empty() || name == MANUAL_DNS || name.starts_with("file:") {
        return Ok(false);
    }
    let fed = secrets_dir.join(format!("secret.dns_{name}"));
    let Ok(bytes) = std::fs::read(&fed) else {
        return Ok(false);
    };
    if bytes.iter().all(u8::is_ascii_whitespace) {
        return Ok(false);
    }
    monetize_cloud::dns::DnsCredential::from_json(&bytes)
        .map_err(|e| format!("{}: {e}", fed.display()))?;
    custody
        .seal_credential(&format!("dns.{name}"), &bytes)
        .map_err(|e| format!("sealing dns.{name}: {e}"))?;
    let _ = std::fs::remove_file(&fed);
    Ok(true)
}

/// **Where [`Installer::sale_check`] looks** (S4): the sold instance's PUBLIC name
/// (`https://<host>`, what the buyer reaches), the account whose `<account>/welcome` must be
/// its one welcome repository, the laid front (its public address, for a world with no DNS
/// for `host`: a mock), the run's directory, and the two secrets the proof needs while the
/// shop still holds them: the console's break-glass bearer (it lists the repositories while
/// no admin passkey exists) and the first-login invite the ready mail will carry. Never
/// logged, never written: `{:?}` withholds them.
pub struct SaleCheckAt<'a> {
    /// What the sold instance's product says it is ([`InstallRequest::facts`]): the sale proof
    /// the check runs is its own.
    pub facts: &'a crate::facts::Facts,
    pub company: &'a str,
    pub host: &'a str,
    pub account: &'a str,
    pub front: Option<&'a monetize_cloud::lay::LaidMachine>,
    pub run_dir: &'a Path,
    pub console_token: &'a str,
    pub first_login: &'a str,
}

impl std::fmt::Debug for SaleCheckAt<'_> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(f, "SaleCheckAt {{ company: {:?}, host: {:?}, account: {:?}, run_dir: {:?}, console_token: <withheld>, first_login: <withheld> }}", self.company, self.host, self.account, self.run_dir)
    }
}

/// How often a sale check that did not pass is asked again (S4): each one asks the sold
/// front for a passkey ceremony, which the front rate-limits per client.
pub const SALE_CHECK_EVERY_MS: u64 = 30 * 1000;

/// The words a missed sale check is parked with (and asked again under).
const SALE_CHECK_MISSED: &str = "the sale check over";

/// How often a buyer may ask for a new sign-in link.
pub const SIGN_IN_AGAIN_EVERY_MS: u64 = 10 * 60 * 1000;

/// How long a queued resend waits for the estate's main to pull it.
pub const SIGN_IN_AGAIN_ORDER_TTL_MS: u64 = 24 * 60 * 60 * 1000;

/// **`EstateOrder.SendSignInAgain`** (S10, owner 2026-10-11 05:53Z): a delivered estate's buyer
/// — the caller proved the order's account — asks for a NEW first-login link. It travels as a
/// SIGNED ORDER ([`kind::SIGN_IN_AGAIN`]) queued for the estate's main: whose account, the
/// order's address, the console host, how long — never a secret. The main pulls it, verifies
/// it under its monetize key, mints the fresh invite itself (only while the account holds no
/// passkey) and mails the link itself: the shop never holds a resend's login secret. (The
/// FIRST link is the shop's, minted at install: OM-21 decision A.) At most once per
/// [`SIGN_IN_AGAIN_EVERY_MS`], a newer ask superseding an unacked older one; never for an
/// order not delivered, nor for an estate the fleet does not hold as sold (no main pulls).
///
/// [`kind::SIGN_IN_AGAIN`]: monetize_embed::fleet::kind::SIGN_IN_AGAIN
pub fn send_sign_in_again(state: &AppState, company: &str) -> Result<String, StartRefusal> {
    let a = ask_sign_in_again(state, company, None)?;
    Ok(format!("a new sign-in link is on its way: {} mints it and mails it to the order's address; it works once, for {}", a.host, a.ttl))
}

/// **A queued `sign_in_again`** ([`ask_sign_in_again`]): the signed order's seq, the host and
/// role it is for, and the link's lifetime in words.
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct SignInAsked {
    pub seq: u64,
    pub host: String,
    pub role: String,
    pub ttl: String,
}

/// [`send_sign_in_again`]'s order, queued: what was asked, never what the main will answer
/// (HOL-MAIL: `site first-link` follows the answer itself). `to` (HOL-FIRST-ADMIN, `site
/// first-link --to`): the address the main mails instead of the order's; it is the run's
/// recorded address from the moment the order is queued (a refused ask changes nothing).
pub fn ask_sign_in_again(
    state: &AppState,
    company: &str,
    to: Option<&str>,
) -> Result<SignInAsked, StartRefusal> {
    use monetize_embed::fleet::{kind, SignInAgain};
    let eo = &state.estates;
    let cfg = eo.cfg.as_ref().ok_or_else(|| {
        StartRefusal::NotSold(
            "this monetize sells no private estates ([estate_orders] is absent)".into(),
        )
    })?;
    let run = eo
        .get(company)
        .filter(|r| !phase::is_gone(&r.phase))
        .ok_or_else(|| StartRefusal::NotFound(format!("no order for {company:?}")))?;
    // FIRST-LINK-1: the run's own name, and the name its boxes pull under — an operator
    // site's is its LABEL (`gunnar-rs`), a sold estate's its company.
    let company = run.company.as_str();
    let fleet = run.fleet_name();
    let host = terms_of(state, cfg, &run)
        .map(|c| c.host_of(company))
        .unwrap_or_else(|_| cfg.host_of(company));
    if !phase::is_term(&run.phase) {
        return Err(StartRefusal::NotNow(format!(
            "{host} is not delivered yet: its ready mail will carry the first sign-in link"
        )));
    }
    if run.account.is_empty() {
        return Err(StartRefusal::NotNow(format!(
            "{host}'s order names no account to sign in as"
        )));
    }
    let now = state.now();
    if run.sign_in_again_at_ms > 0
        && now
            < run
                .sign_in_again_at_ms
                .saturating_add(SIGN_IN_AGAIN_EVERY_MS)
    {
        let left = (run.sign_in_again_at_ms + SIGN_IN_AGAIN_EVERY_MS - now).div_ceil(60_000);
        return Err(StartRefusal::NotNow(format!(
            "a new sign-in link was asked a moment ago; ask again in {left} minute(s)"
        )));
    }
    // The machine that mints and mails the link: the product's primary (Gunnar's main).
    let role = terms_of(state, cfg, &run)
        .and_then(|c| lifecycle::of(&c))
        .or_else(|_| lifecycle::of(cfg))
        .map(|l| l.primary_role())
        .map_err(StartRefusal::NotSold)?;
    let not_pulled = |why: String| {
        StartRefusal::NotNow(format!(
            "{host}'s {role} cannot pull a new sign-in link: {why}"
        ))
    };
    let product = crate::fleet::run_product(state, &run).map_err(not_pulled)?;
    let product = product.as_str();
    let g = state
        .fleet
        .guardian()
        .ok_or_else(|| not_pulled("the fleet store is not open".into()))?;
    if g.store.product_of(fleet).as_deref() != Some(product) {
        return Err(not_pulled(format!(
            "the fleet does not hold {fleet} as a sold estate"
        )));
    }
    let ttl_secs = cfg.first_login_ttl();
    let to = to
        .map(str::trim)
        .filter(|t| !t.is_empty())
        .map(str::to_owned);
    let body = SignInAgain {
        account: run.account.clone(),
        to: to.clone().unwrap_or_else(|| run.email.clone()),
        host: host.clone(),
        ttl_secs,
    };
    let body = serde_json::to_string(&body).map_err(|e| not_pulled(e.to_string()))?;
    let _pen = eo.pen_for_a_call(cfg, company)?;
    let order = monetize_guardian::Guardian::order(
        product,
        fleet,
        &role,
        kind::SIGN_IN_AGAIN,
        body,
        now,
        SIGN_IN_AGAIN_ORDER_TTL_MS,
    );
    let queued = g
        .queue_order(order, |o| o.kind == kind::SIGN_IN_AGAIN && o.role == role)
        .map_err(|e| not_pulled(e.to_string()))?;
    let ttl = ttl_words(ttl_secs);
    if let Some(mut r) = eo.get(company) {
        r.sign_in_again_at_ms = now.max(1);
        let p = r.phase.clone();
        if let Some(to) = to.filter(|t| *t != r.email) {
            r.email = to;
            r.history.push(Transition {
                phase: p.clone(),
                at_ms: now,
                note: format!(
                    "the first admin's address was set by the operator to {}",
                    first_link::masked(&r.email)
                ),
            });
        }
        r.history.push(Transition {
            phase: p,
            at_ms: now,
            note: format!("a new sign-in link for {} was asked: signed order {} ({}) queued for {fleet}'s {role} to pull — the estate mints it and mails it to the order's address", run.account, queued.seq, kind::SIGN_IN_AGAIN),
        });
        kept(state, &r, "a new sign-in link was asked");
    }
    Ok(SignInAsked {
        seq: queued.seq,
        host,
        role,
        ttl,
    })
}

/// The words a shop with no DNS writer refuses an order with (S2, trace-private 2026-10-09).
pub const NO_DNS_WRITER: &str = "this shop writes no DNS records for what it sells ([estate_orders] dns is empty): a sold host would never resolve";

/// The words a shop with no install path refuses an order with (the Sells rule), the product
/// called as `w` says.
pub fn no_install_path(w: &lifecycle::ProductWords) -> String {
    format!("this shop has no way to install a private {} yet ([estate_orders] names no pairing, installer or install worker)", w.title)
}

// ── the run's pen ───────────────────────────────────────────────────────────

/// How long a page's call waits for a run's pen before it is refused as
/// busy ([`StartRefusal::Busy`]). The driver holds it for one step: a
/// vendor's answer, a mail — minutes only while servers are resized or
/// stopped, and then the buyer is told to ask again rather than kept waiting.
pub const PEN_WAIT: Duration = Duration::from_secs(60);

/// **One writer per run at a time** (2026-10-06). The driver read the run,
/// took its step (provider and payment calls) and wrote the WHOLE run back;
/// a `ChangePlan` written in between was gone from the run though the buyer
/// had been answered (MEASURED: the wire test, red 1 run in 3), and the other
/// way a change's write put `grace` back to `captured`. A renewal written
/// over is a page the buyer can pay that nothing captures. And two saves at
/// once share one temp file. So every write holds the run's pen from its read
/// to its write: the driver per step, `Start`, `Renew` and `ChangePlan` for
/// their whole read-modify-write. [`EstateOrders::save`] is only ever called
/// holding it — the saves INSIDE a step (a give-back's progress, the "ready"
/// mail, a resize's progress) are under the driver's pen and take nothing.
///
/// Reads (`Status`, `List`, [`EstateOrders::get`]) never take it: a pen held
/// through a 35-minute install keeps no page waiting.
#[derive(Default)]
struct Pens {
    book: Mutex<PenBook>,
    freed: Condvar,
}

#[derive(Default)]
struct PenBook {
    /// The thread that holds each run's pen.
    held: BTreeMap<String, ThreadId>,
    /// How many writers wait for each.
    waiting: BTreeMap<String, usize>,
}

/// **A run's pen, held**: dropped (or unwound past), the next writer takes it.
pub(crate) struct Pen<'a> {
    pens: &'a Pens,
    company: String,
    /// Taken again on the thread that holds it: nothing to give back.
    nested: bool,
}

impl Drop for Pen<'_> {
    fn drop(&mut self) {
        if !self.nested {
            self.pens
                .book
                .lock()
                .unwrap_or_else(|e| e.into_inner())
                .held
                .remove(&self.company);
            self.pens.freed.notify_all();
        }
    }
}

/// **A run's pen, lent** ([`Pens::lend`]): dropped, the pen is this thread's again.
pub(crate) struct LentPen<'a> {
    pens: &'a Pens,
    company: String,
    lent: bool,
}

impl Drop for LentPen<'_> {
    fn drop(&mut self) {
        if self.lent {
            // Taken back for the guard that lent it: that guard gives it up, not this one.
            std::mem::forget(self.pens.take(&self.company, None));
        }
    }
}

impl Pens {
    /// Take `company`'s pen, waiting at most `wait` (`None`: as long as it takes).
    fn take(&self, company: &str, wait: Option<Duration>) -> Option<Pen<'_>> {
        let me = std::thread::current().id();
        let mut book = self.book.lock().unwrap_or_else(|e| e.into_inner());
        if book.held.get(company) == Some(&me) {
            // A write nested in another on the same thread would be written
            // over by the outer one: a bug, said loudly in a debug build —
            // and never a driver deadlocked on itself in production.
            if cfg!(debug_assertions) {
                panic!("the pen of {company} is taken again on the thread that holds it");
            }
            return Some(Pen {
                pens: self,
                company: company.into(),
                nested: true,
            });
        }
        let give_up = wait.map(|w| Instant::now() + w);
        *book.waiting.entry(company.into()).or_default() += 1;
        while book.held.contains_key(company) {
            book = match give_up {
                None => self.freed.wait(book).unwrap_or_else(|e| e.into_inner()),
                Some(at) => {
                    let left = at.saturating_duration_since(Instant::now());
                    if left.is_zero() {
                        break;
                    }
                    self.freed
                        .wait_timeout(book, left)
                        .unwrap_or_else(|e| e.into_inner())
                        .0
                }
            };
        }
        if let Some(n) = book.waiting.get_mut(company) {
            *n -= 1;
            if *n == 0 {
                book.waiting.remove(company);
            }
        }
        if book.held.contains_key(company) {
            return None;
        }
        book.held.insert(company.into(), me);
        Some(Pen {
            pens: self,
            company: company.into(),
            nested: false,
        })
    }

    /// **Lend `company`'s pen while this thread waits on something slow** (F2: the installer
    /// runs for up to its budget, and an operator's Abandon or the install deadline must reach
    /// the run meanwhile). Held by this thread, it is given up now and taken back, waited for
    /// as long as it takes, when the loan is dropped; not held here, the loan does nothing.
    fn lend(&self, company: &str) -> LentPen<'_> {
        let me = std::thread::current().id();
        let mut book = self.book.lock().unwrap_or_else(|e| e.into_inner());
        let lent = book.held.get(company) == Some(&me);
        if lent {
            book.held.remove(company);
            self.freed.notify_all();
        }
        LentPen {
            pens: self,
            company: company.into(),
            lent,
        }
    }

    /// This thread holds `company`'s pen.
    fn held_here(&self, company: &str) -> bool {
        self.book
            .lock()
            .unwrap_or_else(|e| e.into_inner())
            .held
            .get(company)
            == Some(&std::thread::current().id())
    }
}

// ── the queue ───────────────────────────────────────────────────────────────

/// Each site's own zone writer, by site, with the writer word it was built from.
pub type SiteDns = BTreeMap<String, (String, Arc<dyn EstateDns>)>;

/// **Every private-estate order this server holds**, and what drives them.
pub struct EstateOrders {
    pub cfg: Option<EstateOrderConfig>,
    /// `<data_dir>/estate-orders`; `None`: nothing is written (a server that sells none).
    dir: Option<PathBuf>,
    runs: Mutex<BTreeMap<String, EstateRun>>,
    /// One writer per run ([`Pens`]).
    pens: Pens,
    driving: Mutex<BTreeSet<String>>,
    /// **The front keep boots' jera lane** ([`update::look`]): one queued job per estate whose
    /// update waits for the shop to keep-boot its front; started on the first, on the tick's runtime.
    pub front_keep_lane: std::sync::OnceLock<Arc<jera::jobs::chain::ChainQueue>>,
    /// The keep upgrades running in this shop, by company: one at a time per estate
    /// ([`sold::keep_boot_box`]). Per shop, never process-wide: two shops in one process
    /// (the tests) never refuse each other's.
    pub upgrading: Mutex<BTreeSet<String>>,
    /// **The release-clone sweep's lane** ([`maybe_sweep`]): one jera ChainQueue, started on
    /// the first sweep on the tick's runtime (owner rule: background work is a jera job).
    pub sweep_lane: std::sync::OnceLock<Arc<jera::jobs::chain::ChainQueue>>,
    /// **The DEV-NARRATE receiver's lane** ([`narrate::look`], lane N2): one queued listening
    /// window at a time, started on the first narrated estate on the tick's runtime.
    pub narrate_lane: std::sync::OnceLock<Arc<jera::jobs::chain::ChainQueue>>,
    /// **The New-estate slot's late orders** ([`new_estate::order_when_taken`], OVW-5): one jera
    /// ChainQueue, started on the first site the box took late, on the call's runtime.
    pub new_estate_lane: std::sync::OnceLock<Arc<jera::jobs::chain::ChainQueue>>,
    /// **Each estate's drive lane** ([`tick`], B6): one jera chain per estate, so an estate's
    /// drives run one at a time and two estates never wait for each other.
    pub drive_lanes: Mutex<BTreeMap<String, Arc<jera::jobs::chain::ChainQueue>>>,
    /// When each delivered estate's term was last looked at (in memory).
    term_seen: Mutex<BTreeMap<String, u64>>,
    /// Each run whose site no longer resolves → the reason last said ([`run_terms_said`]).
    terms_said: Mutex<BTreeMap<String, String>>,
    /// Each run's last `Instance` row as booked ([`book`]), in memory.
    booked: Mutex<BTreeMap<String, monetize::Step>>,
    pub installer: Arc<dyn Installer>,
    pub dns: Arc<dyn EstateDns>,
    /// Each site's own zone writer (`[estates.<e>.orders] dns`), over [`EstateOrders::dns`],
    /// with the writer word it was built from. Behind a lock: a site the config watcher takes
    /// in LIVE gets its writer then ([`EstateOrders::follow_site_dns`]) — built only at start,
    /// a site fed after it fell back to the shop's writer (none) and its Sites row read "this
    /// box's DNS token does not write its zone" (test3.gunnar.rs, 2026-10-14).
    pub site_dns: std::sync::RwLock<SiteDns>,
    /// How a customer's own domain is read (`waiting_dns`).
    pub resolver: Arc<dyn DomainCheck>,
    pub custody: Option<Custody>,
    /// Where the twin's lag and load come from (its autoscale).
    pub twin_health: Arc<dyn twin::TwinHealth>,
    /// **`Sells`' last answer and when (unix ms)** — kept [`ladder::SELLS_FRESH_MS`]
    /// ([`sells_now`]), so a console asking every minute never waits on the
    /// provider's price list twice in a row, and an answer that came after a
    /// console stopped waiting is there for its next ask.
    pub sells_seen: Mutex<Option<(bool, u64)>>,
    /// A refresh of `sells_seen` is running in the background (A32).
    pub sells_refreshing: std::sync::atomic::AtomicBool,
    /// **The new-estate ladder as last priced, and when** (A32): the sign-up
    /// page reads it at once while a lay holds the cloud guest for minutes.
    /// The new-estate ladder last priced, and when, per CALLING site (`""`: no site) — each
    /// site's page reads its own terms (private buy flow, 2026-10-12).
    pub ladder_seen: Mutex<BTreeMap<String, (ladder::Ladder, u64)>>,
    /// The sites whose kept ladder is being priced again now.
    pub ladder_refreshing: Mutex<BTreeSet<String>>,
    /// **Tests only**: keep a sold estate's secrets after its hand-off. The
    /// twin's health reading goes through the estate's door with its pairing
    /// material until the estate issues a read-only health token (round
    /// 5.3.1); production FORGETS them (2026-10-08) and nothing sets this.
    pub keep_secrets_for_health_reads: std::sync::atomic::AtomicBool,
    /// **One admission at a time** (the UpCloud mockup run 4, 2026-10-08: two paid
    /// orders driven at once both read the other as not yet laying and both were laid
    /// past `max_estates` 1): held from the queue's look until the admitted order reads
    /// LAYING in [`Self::runs`].
    pub admitting: Mutex<()>,
    /// When the release-clone sweep last ran ([`maybe_sweep`]); 0: not yet.
    pub swept_at: Mutex<u64>,
    /// Where the kit's fed READ pair of the release bucket lands ([`MEDIA_OBJSTO_FED`]).
    pub media_key_fed: Option<PathBuf>,
    /// The host's secrets directory the sold estates' relay is read from ([`relay_feed`]).
    pub relay_fed: Option<PathBuf>,
}

impl Default for EstateOrders {
    fn default() -> Self {
        EstateOrders {
            cfg: None,
            dir: None,
            runs: Mutex::default(),
            pens: Pens::default(),
            driving: Mutex::default(),
            front_keep_lane: Default::default(),
            upgrading: Mutex::default(),
            sweep_lane: Default::default(),
            narrate_lane: Default::default(),
            new_estate_lane: Default::default(),
            drive_lanes: Mutex::default(),
            term_seen: Mutex::default(),
            terms_said: Mutex::default(),
            booked: Mutex::default(),
            sells_seen: Mutex::default(),
            sells_refreshing: Default::default(),
            ladder_seen: Mutex::default(),
            ladder_refreshing: Default::default(),
            keep_secrets_for_health_reads: Default::default(),
            admitting: Mutex::default(),
            swept_at: Mutex::default(),
            media_key_fed: None,
            relay_fed: None,
            site_dns: Default::default(),
            installer: Arc::new(NoInstaller),
            dns: Arc::new(NoDns),
            resolver: Arc::new(NoResolver),
            custody: None,
            twin_health: Arc::new(twin::NoTwinHealth),
        }
    }
}

/// Write `bytes` to `path` atomically: a temp file, fsync, rename.
fn write_atomic(path: &Path, bytes: &[u8]) -> Result<(), String> {
    use std::io::Write as _;
    if let Some(d) = path.parent() {
        std::fs::create_dir_all(d).map_err(|e| format!("{}: {e}", d.display()))?;
    }
    let tmp = path.with_extension("tmp");
    let mut f = std::fs::File::create(&tmp).map_err(|e| format!("{}: {e}", tmp.display()))?;
    f.write_all(bytes)
        .and_then(|_| f.sync_all())
        .map_err(|e| format!("{}: {e}", tmp.display()))?;
    std::fs::rename(&tmp, path).map_err(|e| format!("{}: {e}", path.display()))
}

impl EstateOrders {
    /// The server's: `[estate_orders]` read, every run read back from its file
    /// (a torn one set aside as `run.json.torn` and named on stderr) — with
    /// the open set of DNS writers ([`Self::from_config_with`] for a build's own).
    pub fn from_config(cfg: &crate::config::Config) -> anyhow::Result<Self> {
        Self::from_config_with(cfg, &crate::registry::Linked::open())
    }

    /// [`Self::from_config`], with the DNS writers `linked` can build:
    /// `dns = "file:<path>"` is the mock's recording file, `""` is no writer,
    /// any other word is a LINKED writer by name (`cloudflare`), refused by
    /// name when this build has none — its zone and token unsealed from the
    /// custodian (`dns.<name>`) for each call.
    pub fn from_config_with(
        cfg: &crate::config::Config,
        linked: &crate::registry::Linked,
    ) -> anyhow::Result<Self> {
        let Some(mut c) = cfg.estate_orders.clone() else {
            return Ok(Self::default());
        };
        price::sale_currency(&c).map_err(|e| anyhow::anyhow!(e))?;
        c.term.check().map_err(|e| anyhow::anyhow!(e))?;
        if c.spend_cap_monthly_minor == 0 {
            anyhow::bail!("[estate_orders] spend_cap_monthly_minor is 0: every private estate has a spend cap");
        }
        let pairing = c.pairing.trim().to_string();
        if !c.install_workers.is_empty() {
            anyhow::bail!("{WORKERS_REMOVED}");
        }
        if !c.twin_health.is_empty() {
            anyhow::bail!("{TWIN_HEALTH_COMMAND_REMOVED}");
        }
        c.shop_door().map_err(|e| anyhow::anyhow!(e))?;
        // OM-4 (one monetize, the owner 2026-10-10): the product a sold
        // estate is, named or derived — never a hard-coded "gunnar".
        let named = c.product.trim().to_string();
        if named.is_empty() {
            match (cfg.pricing.len(), cfg.pricing.keys().next()) {
                (1, Some(only)) => c.product = only.clone(),
                (0, _) => anyhow::bail!("[estate_orders] product is not set and no [pricing.<product>] names one: name the product a sold estate is"),
                _ => anyhow::bail!(
                    "[estate_orders] product is not set and this box prices several products ({}): name the one a sold estate is",
                    cfg.pricing.keys().cloned().collect::<Vec<_>>().join(", ")
                ),
            }
        } else {
            c.product = named;
        }
        // The product's KIND (its `[products.<id>] plugin`) picks its lifecycle (`lifecycle::of`).
        c.lifecycle = cfg
            .products
            .get(&c.product)
            .and_then(|p| p.plugin.clone())
            .unwrap_or_default();
        // The shape: the file's, else the lifecycle's default (a kind with none keeps the type's).
        c.shape = match (
            &c.shape_given,
            lifecycle::of(&c).ok().and_then(|l| l.default_shape()),
        ) {
            (Some(given), _) => given.clone(),
            (None, Some(own)) => own,
            (None, None) => c.shape.clone(),
        };
        if !pairing.is_empty() {
            media_missing_on_sites(&c, &cfg.estates)
                .map_or(Ok(()), |why| Err(anyhow::anyhow!(why)))?;
        }
        let installer: Arc<dyn Installer> = if !pairing.is_empty() {
            linked_installer(&c, linked, &cfg.data_dir).map_err(|e| anyhow::anyhow!(e))?
        } else {
            Arc::new(NoInstaller)
        };
        let custody =
            Custody::open(cfg.data_dir.join("custody")).map_err(|e| anyhow::anyhow!(e))?;
        let resolver = domain::resolver_of(&c.resolver).map_err(|e| anyhow::anyhow!(e))?;
        // S2: the DNS writer's credential FED by the kit (`secret.dns_<name>`) is sealed into the
        // custody, where the writer unseals it for each call.
        let mut writers: Vec<String> = vec![c.dns.trim().to_owned()];
        writers.extend(site_dns_writers(&cfg.estates).into_values());
        writers.sort();
        writers.dedup();
        for w in writers.iter().filter(|w| !w.is_empty()) {
            match seal_fed_dns(&custody, &cfg.secrets_dir(), w) {
                Ok(true) => eprintln!("monetize-server: estate orders: the fed DNS credential for {w:?} is sealed in the custody"),
                Ok(false) => {}
                Err(e) => anyhow::bail!(e),
            }
        }
        // A writer this build does not link refuses by NAME where it would write; the shop
        // and every other zone keep serving (2026-10-11).
        // The guest writers read their token from the FED secrets directory, as the clouds do.
        let dns_guests = dns_guest_blocks(&cfg.dns_writers, &cfg.secrets_dir());
        let dns: Arc<dyn EstateDns> = writer_or_refused(
            &c,
            linked,
            &custody,
            resolver.clone(),
            &dns_guests,
            &cfg.data_dir,
        );
        let mut site_dns = BTreeMap::new();
        for (id, w) in site_dns_writers(&cfg.estates) {
            let one = EstateOrderConfig {
                dns: w.clone(),
                ..c.clone()
            };
            let writer = writer_or_refused(
                &one,
                linked,
                &custody,
                resolver.clone(),
                &dns_guests,
                &cfg.data_dir,
            );
            site_dns.insert(id, (w, writer));
        }
        if !dns.writes() && !site_dns.values().any(|(_, d)| d.writes()) {
            eprintln!("monetize-server: estate orders: ALERT estate-orders.dns-writer {NO_DNS_WRITER} — this shop sells nothing until a zone it sells under names a linked writer");
        }
        let mut orders = Self::with(
            c,
            cfg.data_dir.join("estate-orders"),
            installer,
            dns,
            custody,
        )
        .resolving(resolver)
        .watching(Arc::new(twin::ReportedTwinHealth));
        orders.site_dns = std::sync::RwLock::new(site_dns);
        orders.media_key_fed = Some(cfg.secrets_dir().join(MEDIA_OBJSTO_FED));
        orders.relay_fed = Some(cfg.secrets_dir());
        if let Some(alert) = unsuffixed_relay_alert(&cfg.secrets_dir()) {
            eprintln!("monetize-server: estate orders: {alert}");
        }
        Ok(orders)
    }

    /// The writer of `estate`'s zone: its own (`[estates.<e>.orders] dns`), else the shop's.
    /// Stub until GREEN.
    pub fn dns_on(&self, estate: &str) -> Arc<dyn EstateDns> {
        self.site_dns
            .read()
            .unwrap_or_else(|e| e.into_inner())
            .get(estate.trim())
            .map(|(_, d)| d.clone())
            .unwrap_or_else(|| self.dns.clone())
    }

    /// The NAME of the writer of `estate`'s zone: its own, else the shop's (`[estate_orders] dns`).
    pub fn dns_name_on(&self, estate: &str) -> String {
        let own = self
            .site_dns
            .read()
            .unwrap_or_else(|e| e.into_inner())
            .get(estate.trim())
            .map(|(w, _)| w.clone());
        own.unwrap_or_else(|| {
            self.cfg
                .as_ref()
                .map(|c| c.dns.trim().to_owned())
                .unwrap_or_default()
        })
    }

    /// **The writer named `name`**, when this shop holds one: a site's, or the shop's own.
    pub fn dns_named(&self, name: &str) -> Option<Arc<dyn EstateDns>> {
        let name = name.trim();
        if name.is_empty() {
            return None;
        }
        let site = self
            .site_dns
            .read()
            .unwrap_or_else(|e| e.into_inner())
            .values()
            .find(|(w, _)| w == name)
            .map(|(_, d)| d.clone());
        site.or_else(|| {
            self.cfg
                .as_ref()
                .filter(|c| c.dns.trim() == name)
                .map(|_| self.dns.clone())
        })
    }

    /// **The writer of a run's names** (DNS-WRITER, 2026-10-26): the one that WROTE them
    /// ([`EstateRun::dns_writer`]) while this shop holds it, else the site's of now. The line
    /// says when the two differ (the site's writer changed since the names were written), and
    /// is an ALERT when the one that wrote them is not held any more.
    pub fn dns_of_run(&self, run: &EstateRun) -> (Arc<dyn EstateDns>, Option<String>) {
        let now = self.dns_name_on(&run.estate);
        let wrote = run.dns_writer.trim();
        if wrote.is_empty() || wrote == now {
            return (self.dns_on(&run.estate), None);
        }
        match self.dns_named(wrote) {
            Some(d) => (d, Some(format!("its DNS names were written by {wrote:?}, so they are removed there (the site writes with {now:?} now)"))),
            None => (self.dns_on(&run.estate), Some(format!("ALERT: its DNS names were written by {wrote:?}, which this shop no longer holds; they are looked for with {now:?}"))),
        }
    }

    /// Whether any zone this shop sells under is written (the shop's own, or a site's).
    pub fn writes_anywhere(&self) -> bool {
        self.dns.writes()
            || self
                .site_dns
                .read()
                .unwrap_or_else(|e| e.into_inner())
                .values()
                .any(|(_, d)| d.writes())
    }

    /// Give `estate` a writer of its own (built from `[estates.<e>.orders] dns`). Stub.
    pub fn site_dns(self, estate: &str, writer: Arc<dyn EstateDns>) -> Self {
        self.site_dns
            .write()
            .unwrap_or_else(|e| e.into_inner())
            .insert(estate.to_owned(), (String::new(), writer));
        self
    }

    /// **Each site's zone writer follows the config LIVE** (the config watcher, every change):
    /// a site of the product sold here whose `[estates.<e>.orders] dns` is new or names another
    /// writer gets it built now ([`writer_or_refused`], as at start); a site that names none any
    /// more falls back to the shop's. Before 2026-10-14 the writers were built at start only, so
    /// a site the watcher took in (test3.gunnar.rs) read the shop's writer — none — and its
    /// Sites row said "this box's DNS token does not write its zone" while test2, in the same
    /// Cloudflare zone, wrote. Answers a line per change.
    pub fn follow_site_dns(
        &self,
        cfg: &crate::config::Config,
        linked: &crate::registry::Linked,
    ) -> Vec<String> {
        let (Some(c), Some(custody)) = (self.cfg.as_ref(), self.custody.as_ref()) else {
            return Vec::new();
        };
        let wanted: BTreeMap<String, String> = site_dns_writers(&cfg.estates);
        let held: BTreeMap<String, String> = self
            .site_dns
            .read()
            .unwrap_or_else(|e| e.into_inner())
            .iter()
            .map(|(k, (w, _))| (k.clone(), w.clone()))
            .collect();
        let mut lines = Vec::new();
        let guests = dns_guest_blocks(&cfg.dns_writers, &cfg.secrets_dir());
        for (id, w) in &wanted {
            if held.get(id) == Some(w) {
                continue;
            }
            if let Err(e) = seal_fed_dns(custody, &cfg.secrets_dir(), w) {
                lines.push(format!(
                    "estate orders: the site {id}'s DNS writer {w:?}: {}",
                    log_safe(&e)
                ));
            }
            let one = EstateOrderConfig {
                dns: w.clone(),
                ..c.clone()
            };
            let writer = writer_or_refused(
                &one,
                linked,
                custody,
                self.resolver.clone(),
                &guests,
                &cfg.data_dir,
            );
            lines.push(format!(
                "estate orders: the site {id} writes its zone with {w:?}{}",
                if writer.writes() {
                    ""
                } else {
                    " — REFUSED, see the ALERT"
                }
            ));
            self.site_dns
                .write()
                .unwrap_or_else(|e| e.into_inner())
                .insert(id.clone(), (w.clone(), writer));
        }
        let mut map = self.site_dns.write().unwrap_or_else(|e| e.into_inner());
        let gone: Vec<String> = map
            .iter()
            .filter(|(k, (w, _))| !w.is_empty() && !wanted.contains_key(*k))
            .map(|(k, _)| k.clone())
            .collect();
        for id in gone {
            map.remove(&id);
            lines.push(format!("estate orders: the site {id} names no DNS writer any more: the shop's writes its zone"));
        }
        lines
    }

    /// Built from parts (the tests', and `from_config`'s).
    pub fn with(
        cfg: EstateOrderConfig,
        dir: PathBuf,
        installer: Arc<dyn Installer>,
        dns: Arc<dyn EstateDns>,
        custody: Custody,
    ) -> Self {
        let mut runs = BTreeMap::new();
        if let Ok(rd) = std::fs::read_dir(&dir) {
            for e in rd.flatten() {
                let file = e.path().join("run.json");
                let Ok(bytes) = std::fs::read(&file) else {
                    continue;
                };
                match serde_json::from_slice::<EstateRun>(&bytes) {
                    Ok(run) => {
                        runs.insert(run.company.clone(), run);
                    }
                    Err(err) => {
                        let _ = std::fs::rename(&file, file.with_extension("json.torn"));
                        eprintln!("monetize-server: estate order {}: the run file would not parse ({err}); set aside as run.json.torn", file.display());
                    }
                }
            }
        }
        EstateOrders {
            cfg: Some(cfg),
            dir: Some(dir),
            runs: Mutex::new(runs),
            pens: Pens::default(),
            driving: Mutex::default(),
            front_keep_lane: Default::default(),
            upgrading: Mutex::default(),
            sweep_lane: Default::default(),
            narrate_lane: Default::default(),
            new_estate_lane: Default::default(),
            drive_lanes: Mutex::default(),
            term_seen: Mutex::default(),
            terms_said: Mutex::default(),
            booked: Mutex::default(),
            sells_seen: Mutex::default(),
            sells_refreshing: Default::default(),
            ladder_seen: Mutex::default(),
            ladder_refreshing: Default::default(),
            keep_secrets_for_health_reads: Default::default(),
            admitting: Mutex::default(),
            swept_at: Mutex::default(),
            media_key_fed: None,
            relay_fed: None,
            site_dns: Default::default(),
            installer,
            dns,
            resolver: Arc::new(NoResolver),
            custody: Some(custody),
            twin_health: Arc::new(twin::NoTwinHealth),
        }
    }

    /// The same, reading customers' domains through `resolver`.
    pub fn resolving(mut self, resolver: Arc<dyn DomainCheck>) -> Self {
        self.resolver = resolver;
        self
    }

    /// The same, reading the twins' lag and load through `health`.
    pub fn watching(mut self, health: Arc<dyn twin::TwinHealth>) -> Self {
        self.twin_health = health;
        self
    }

    pub fn get(&self, company: &str) -> Option<EstateRun> {
        let runs = self.runs.lock().unwrap_or_else(|e| e.into_inner());
        // An operator site laid here is also found by its own label (its fleet name).
        runs.get(company).cloned().or_else(|| {
            runs.values()
                .find(|r| r.site_order && r.estate == company)
                .cloned()
        })
    }

    pub fn all(&self) -> Vec<EstateRun> {
        self.runs
            .lock()
            .unwrap_or_else(|e| e.into_inner())
            .values()
            .cloned()
            .collect()
    }

    /// The job's own directory: `<dir>/<company>`.
    pub fn run_dir(&self, company: &str) -> Option<PathBuf> {
        self.dir.as_ref().map(|d| d.join(company))
    }

    /// The cloud's journal of this estate's lay.
    /// `<data_dir>/estate-orders`, when this server writes.
    pub fn dir(&self) -> Option<&std::path::Path> {
        self.dir.as_deref()
    }

    pub fn journal(&self, company: &str) -> Result<monetize_cloud::grow::Journal, String> {
        let dir = self.run_dir(company).ok_or("no estate-orders directory")?;
        std::fs::create_dir_all(&dir).map_err(|e| format!("{}: {e}", dir.display()))?;
        monetize_cloud::grow::Journal::open(dir.join("journal")).map_err(|e| e.to_string())
    }

    /// Write the run, then keep it: the file first, so memory never says
    /// what the disk does not. Only ever called holding the run's pen —
    /// through [`save`], which also books the run's ledger row.
    fn write(&self, run: &EstateRun) -> Result<(), String> {
        debug_assert!(
            self.pens.held_here(&run.company),
            "the run of {} is written without its pen",
            run.company
        );
        if let Some(dir) = self.run_dir(&run.company) {
            let bytes = serde_json::to_vec_pretty(run).map_err(|e| e.to_string())?;
            write_atomic(&dir.join("run.json"), &bytes)?;
        }
        self.runs
            .lock()
            .unwrap_or_else(|e| e.into_inner())
            .insert(run.company.clone(), run.clone());
        Ok(())
    }

    /// **The run's pen, waited for as long as it takes** — the driver's: a
    /// page's call holds it only for its own few calls.
    pub(crate) fn pen(&self, company: &str) -> Pen<'_> {
        // A wait without a limit returns only holding the pen; asking again
        // is the answer if it ever did not.
        loop {
            if let Some(pen) = self.pens.take(company, None) {
                return pen;
            }
        }
    }

    /// [`Pens::lend`] on this server's pens.
    fn lend_pen(&self, company: &str) -> LentPen<'_> {
        self.pens.lend(company)
    }

    /// **The run's pen for the tick**, only when nobody holds it now.
    fn try_pen(&self, company: &str) -> Option<Pen<'_>> {
        self.pens.take(company, Some(Duration::ZERO))
    }

    /// **The run's pen for a page's call**: waited for at most [`PEN_WAIT`],
    /// then refused as busy — before anything was held or changed.
    fn pen_for_a_call(
        &self,
        cfg: &EstateOrderConfig,
        company: &str,
    ) -> Result<Pen<'_>, StartRefusal> {
        self.pens.take(company, Some(PEN_WAIT)).ok_or_else(|| {
            StartRefusal::Busy(format!("{} is being worked on right now; ask again in a minute — nothing was held or changed", cfg.host_of(company)))
        })
    }

    /// **How many writers wait for this run's pen** — the tests' window on
    /// the one-writer rule.
    #[cfg(test)]
    pub(crate) fn pen_waiters(&self, company: &str) -> usize {
        self.pens
            .book
            .lock()
            .unwrap_or_else(|e| e.into_inner())
            .waiting
            .get(company)
            .copied()
            .unwrap_or(0)
    }
}

// ── starting an order ───────────────────────────────────────────────────────

/// Why `Start` said no — each maps to its own gRPC code.
#[derive(Debug, PartialEq, Eq)]
pub enum StartRefusal {
    /// This server sells no private estates.
    NotSold(String),
    /// The name breaks the rule.
    BadName(String),
    /// The name is taken (an order in progress, or a delivered estate).
    Taken(String),
    /// The vendor said no, or is not linked.
    Vendor(String),
    /// The provider's answer cannot be priced (or not at our margin, or over the spend cap).
    Price(String),
    /// Not now: a renewal before its window opens, or of an estate in no state to renew.
    NotNow(String),
    /// The run's pen stayed taken past [`PEN_WAIT`]: ask again (nothing was held).
    Busy(String),
    /// No such order (a read that names one nobody placed).
    NotFound(String),
}

impl std::fmt::Display for StartRefusal {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            StartRefusal::NotSold(w)
            | StartRefusal::BadName(w)
            | StartRefusal::Taken(w)
            | StartRefusal::Vendor(w)
            | StartRefusal::Price(w)
            | StartRefusal::NotNow(w)
            | StartRefusal::Busy(w)
            | StartRefusal::NotFound(w) => f.write_str(w),
        }
    }
}

/// **`EstateOrder.Quote`**: price an estate of these sizes now, from the
/// provider's own answer. Moves nothing.
pub fn quote(state: &AppState, company: &str, sizes: &EstateSizes) -> Result<Quote, StartRefusal> {
    let cfg = state.estates.cfg.as_ref().ok_or_else(|| {
        StartRefusal::NotSold(
            "this monetize sells no private estates ([estate_orders] is absent)".into(),
        )
    })?;
    quote_on(state, cfg, company, sizes)
}

/// [`quote`] on the terms `cfg` — a site's own ([`terms_on`]): its margin and its term price
/// and hold the order, the same terms the lay's recheck holds it to (turn run6 A3).
pub fn quote_on(
    state: &AppState,
    cfg: &EstateOrderConfig,
    company: &str,
    sizes: &EstateSizes,
) -> Result<Quote, StartRefusal> {
    let cloud = state.registry.find_cloud(&cfg.cloud).ok_or_else(|| {
        StartRefusal::NotSold(format!("the cloud {:?} is not linked here", cfg.cloud))
    })?;
    let name = if company.is_empty() { "quote" } else { company };
    // The product's own order, checked against its form (a product with no lifecycle quotes
    // as before and is refused at the start).
    let sizes = &match lifecycle::of(cfg) {
        Ok(l) => price::order_of(&l.facts(), sizes).map_err(StartRefusal::BadName)?,
        Err(_) => sizes.clone(),
    };
    let q = price::quote(cfg, cloud, name, sizes).map_err(StartRefusal::Price)?;
    // **The spend cap per estate is never the buyer's to meet** (the owner,
    // 2026-10-08: "the customer must not know about a cap"; wiring trace
    // A03): every size is offered and sold, and an order over the cap WAITS
    // in the queue until the operator raises it (`queue_admits`).
    Ok(q)
}

/// **What the estate's OWN monetize grew, read back** (private ownership
/// (d), 2026-10-07): main's data set (and the twin's disk after it) grows
/// under the order's headroom by the estate's own monetize, on the seller's
/// cloud account — the disks keep their ids and get bigger. The provider's
/// inventory is read and every laid disk takes its size there when larger
/// (a disk never shrinks); the run's quoted `main_data_gib` follows main's
/// data members, so the renewal, the ladder's floor and every later quote are
/// priced from what is LAID, not from what was ordered. Answers the line to
/// note when something grew.
pub fn refresh_laid(
    state: &AppState,
    cfg: &EstateOrderConfig,
    run: &mut EstateRun,
) -> Result<Option<String>, String> {
    if run.laid.is_none() {
        return Ok(None);
    }
    // The primary (Gunnar's main) is the machine whose data members the quote's data size is.
    let primary = lifecycle::of(cfg)?.primary_role();
    let cloud = state
        .registry
        .find_cloud(&cfg.cloud)
        .ok_or_else(|| format!("the cloud {:?} is not linked here", cfg.cloud))?;
    let inv = monetize_cloud::ask::account(&cloud)
        .map_err(|e| format!("the provider's inventory could not be read: {e}"))?;
    // A provider may answer an id with its provider's prefix (`upcloud/…`).
    let size_of = |id: &str| {
        inv.owned
            .iter()
            .filter(|o| o.kind == monetize_cloud::OwnedKind::Disk)
            .find(|o| o.id.id == id || o.id.id.ends_with(&format!("/{id}")))
            .map(|o| o.gib)
    };
    let mut grew = false;
    let (members, data, lines) = {
        let Some(laid) = run.laid.as_mut() else {
            return Ok(None);
        };
        for m in laid.machines.iter_mut() {
            for d in m.disks.iter_mut() {
                // A disk never shrinks: only a larger size is taken.
                if let Some(g) = size_of(&d.id).filter(|g| *g > d.gib) {
                    d.gib = g;
                    grew = true;
                }
            }
        }
        let main = laid.machine(&primary);
        let members = main.map(|m| m.disks.len().saturating_sub(1)).unwrap_or(0);
        let data = main
            .and_then(|m| m.disks.iter().skip(1).map(|d| d.gib).min())
            .unwrap_or(0);
        let lines: Vec<(String, Vec<u64>)> = laid
            .machines
            .iter()
            .map(|m| (m.role.clone(), m.disks.iter().map(|d| d.gib).collect()))
            .collect();
        (members, data, lines)
    };
    if !grew && data <= run.quote.sizes.main_data_gib {
        return Ok(None);
    }
    run.quote.sizes.main_data_gib = run.quote.sizes.main_data_gib.max(data);
    for line in run.quote.machines.iter_mut() {
        if let Some((_, disks)) = lines.iter().find(|(role, _)| *role == line.role) {
            line.disks_gib = disks.clone();
        }
    }
    Ok(Some(format!("{primary}'s data is laid at {members} × {data} GB now (the estate's own monetize grew it); its renewal and every later price are from what is laid")))
}

/// **The price of a delivered estate NOW**, as it stands: its sizes, the
/// twin it has (as it was laid, or as it grew), the provider's price today +
/// the margin. No cap is
/// applied here: the estate's own cap is the caller's (`term::within_cap`).
pub fn quote_for_run(state: &AppState, run: &EstateRun) -> Result<Quote, StartRefusal> {
    let base = state.estates.cfg.as_ref().ok_or_else(|| {
        StartRefusal::NotSold(
            "this monetize sells no private estates ([estate_orders] is absent)".into(),
        )
    })?;
    // the run's site's own terms, as its Start and its lay (turn run6 A3)
    let site_terms = terms_of(state, base, run).map_err(StartRefusal::NotSold)?;
    let cfg = &site_terms;
    let cloud = state.registry.find_cloud(&cfg.cloud).ok_or_else(|| {
        StartRefusal::NotSold(format!("the cloud {:?} is not linked here", cfg.cloud))
    })?;
    // **What is LAID is what is priced** (2026-10-13): the twin this estate has, never the
    // one the rule would give a new order of its sizes — an estate laid with a 2 GB twin
    // before the 4 GB floor is not charged for a twin it does not have, and is not resized.
    let laid_twin = run
        .laid
        .as_ref()
        .and_then(|l| l.machine("twin"))
        .map(|m| m.plan.as_str())
        .unwrap_or("");
    price::quote_as_laid(
        &priced_for(cfg, run.operator_test),
        cloud,
        &run.company,
        &run.quote.sizes,
        &run.twin_floor,
        laid_twin,
    )
    .map_err(StartRefusal::Price)
}

/// **The names a new estate keeps for itself** (private ownership,
/// 2026-10-07): the install's bootstrap admin (it holds the seller's key),
/// the shop's own machines and the anonymous reader — no buyer's account.
/// A product's own machine principals are its facts' `reserved_accounts`.
pub const RESERVED_ACCOUNTS: &[&str] = &[
    "admin",
    "anonymous",
    "monetize",
    "front-certify",
    "installer-seed",
];
/// The prefixes of the names it keeps: a laid-again front's restore
/// identities and the kit's own machine credentials.
pub const RESERVED_ACCOUNT_PREFIXES: &[&str] = &["monetize-restore-", "kit-"];

/// Pure: why `account` cannot be a buyer's, or `None`: the shop's own names, and the ones the
/// product keeps for its own machines (`own`, its facts' `reserved_accounts`); the product
/// called as `w` says.
pub fn reserved_account_as(
    account: &str,
    own: &[String],
    w: &lifecycle::ProductWords,
) -> Option<String> {
    (RESERVED_ACCOUNTS.contains(&account) || own.iter().any(|o| o == account) || RESERVED_ACCOUNT_PREFIXES.iter().any(|p| account.starts_with(p)))
        .then(|| format!("the account name {account:?} is one the new {} keeps for itself (its install's admin or one of its own machines): choose another", w.title))
}

/// **Write the run and book its row** (G5, 5.4): the run file first
/// ([`EstateOrders::write`]), then its `Instance` row on the owner's gunnar
/// account ([`book`]). Every writer of a run goes through here, holding the
/// run's pen.
pub(crate) fn save(state: &AppState, run: &EstateRun) -> Result<(), String> {
    let before = state
        .estates
        .get(&run.company)
        .filter(|r| r.ordered_at_ms == run.ordered_at_ms)
        .map(|r| r.history.len())
        .unwrap_or(0);
    state.estates.write(run)?;
    // A run written down again clears what [`kept`] raised for it.
    code_red::clear(state, &unsaved_key(&run.company));
    // Every phase the order moved to is a live setup line (the test button).
    setup_log::publish_transitions(&state.bus, &instance_product(state), run, before);
    book(state, run);
    Ok(())
}

fn unsaved_key(company: &str) -> String {
    format!("save:{company}:run")
}

/// **[`save`], said when it fails** (A28 M16: three sites dropped it, `let _ = save`): CODE
/// RED `save:<estate>:run` names what was not written down `after`, and the next write of the
/// run clears it. `false`: not written — memory is ahead of the disk until it is.
pub(crate) fn kept(state: &AppState, run: &EstateRun, after: &str) -> bool {
    let Err(e) = save(state, run) else {
        return true;
    };
    let site = state
        .estates
        .cfg
        .as_ref()
        .map(|c| c.host_of(&run.company))
        .unwrap_or_else(|| run.company.clone());
    code_red::raise(
        state,
        &unsaved_key(&run.company),
        &site,
        "the ONE box",
        &format!("the estate's run was NOT written after {after}: memory and disk disagree, and a restart forgets it"),
        &e,
        "fix what the error names (the data directory: full, read-only or gone); the next write of the run clears this",
    );
    false
}

/// **The product this shop's estates are rows of**: its `[estate_orders]` product's lifecycle
/// kind ([`lifecycle::instance_product`]) — `gunnar` on a box that sells Gunnar.
pub fn instance_product(state: &AppState) -> String {
    lifecycle::instance_product(state.estates.cfg.as_ref())
}

/// Pure: **the run as its ledger row** — on `(gunnar, run.account)`, the
/// account the order was proven for; `None` for a run that names none.
pub fn instance_step(cfg: Option<&EstateOrderConfig>, run: &EstateRun) -> Option<monetize::Step> {
    let tenant = run.account.trim();
    if tenant.is_empty() {
        return None;
    }
    let host = if !run.domain.is_empty() {
        run.domain.clone()
    } else {
        cfg.map(|c| c.host_of(&run.company)).unwrap_or_default()
    };
    let product = lifecycle::instance_product(cfg);
    Some(monetize::Step::Instance {
        reference: monetize::ledger::instance_reference(
            &product,
            tenant,
            run.ordered_at_ms,
            &run.company,
        ),
        product,
        tenant: tenant.into(),
        company: run.company.clone(),
        host,
        phase: run.phase.clone(),
        monthly: run.quote.monthly,
        paid_until_unix_ms: run.paid_until_ms,
        vendor: run
            .handle
            .as_ref()
            .map(|h| h.vendor.clone())
            .unwrap_or_default(),
        operator_test: run.operator_test,
        note: String::new(),
    })
}

/// **Book the run's row on its owner's gunnar account** (G5): appended only
/// when it says something the account's last row for this estate does not
/// (the ledger keeps the same line once). A refusal is an ALERT, not the
/// run's failure: the next [`tick`] books it again.
pub(crate) fn book(state: &AppState, run: &EstateRun) {
    // A run stopped by name is not asked for its terms on every tick (PROD-FIX 2).
    if !run.stopped_why.is_empty() {
        return;
    }
    // OVW-2 (prod 2026-10-29: `REFUSED [estate-undeclared] test3-holger-rs`, a run terminated
    // on 10-23): a GONE run has nothing more to bill. Its terms are read without a word, and
    // once its site left the feed it is not booked at all (with no terms its row would name the
    // shop's default product).
    let terms = if phase::is_gone(&run.phase) {
        match state
            .estates
            .cfg
            .as_ref()
            .map(|base| terms_of(state, base, run))
        {
            Some(Ok(c)) => Some(c),
            Some(Err(_)) => return,
            None => None,
        }
    } else {
        // ★ ST-4/ST-5: on the account of the run's OWN site (`@<site>/<account>` away from
        // home) and named on that site.
        run_terms(state, run)
    };
    let booked = EstateRun {
        account: ledger_account(state, run),
        ..run.clone()
    };
    let Some(step) = instance_step(terms.as_ref(), &booked) else {
        return;
    };
    if state
        .estates
        .booked
        .lock()
        .unwrap_or_else(|e| e.into_inner())
        .get(&run.company)
        == Some(&step)
    {
        return;
    }
    match state.ledger.append(state.now(), step.clone()) {
        Ok(_) => {
            state.estates.booked.lock().unwrap_or_else(|e| e.into_inner()).insert(run.company.clone(), step);
        }
        Err(e) => eprintln!("monetize-server: ALERT estate-orders.account-row estate order {}: its row on the account {:?} is not written ({e}); the next tick tries again", run.company, run.account),
    }
}

/// **`EstateOrder.Start`**: reserve the name, price the estate from the
/// provider's answer (+ the margin, six months prepaid), ask the vendor for
/// the hold, write the run (`ordered`) and its row on the owner's gunnar
/// account. Nothing is laid here — nothing is laid before the vendor says the
/// money is held.
///
/// The order names its OWNER: the account name its first admin is to have
/// (monetize's username rule, and never a name the estate keeps for itself —
/// [`reserved_account_as`]). Kept in the run, handed to the installer, and the
/// tenant of its ledger row (G5). None named is refused here, before any
/// hold: a private Gunnar is its buyer's.
pub fn start_for(
    state: &AppState,
    company: &str,
    email: &str,
    own_domain: &str,
    account: &str,
    sizes: &EstateSizes,
) -> Result<EstateRun, StartRefusal> {
    start_with(
        state,
        company,
        email,
        own_domain,
        account,
        sizes,
        &OrderedBy::Buyer,
    )
}

/// [`start_for`] from the site `estate` (the caller's own bearer, [`crate::auth::CallerEstate`]):
/// held through that site's own account and named on that site ([`terms_on`], ST-5).
pub fn start_on(
    state: &AppState,

The file goes on; the console shows all of it.